2e8827e5b98f33be1dc8b844d026da06a1c86ae8
[projects/chimara/chimara.git] / tests / babeltest.c
1 #include "babel/babel_handler.h"
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <glib.h>
7 #include <glib/gprintf.h>
8 #include <libgda/libgda.h>
9 #include <libgda/sql-parser/gda-sql-parser.h>
10 #include <libsoup/soup.h>
11
12 typedef struct _metadata {
13         const gchar *element_name;
14         gchar *ifid;
15         gchar *title;
16         gchar *author;
17         gchar *firstpublished;
18         gboolean error;
19         gchar *error_message;
20         gchar *error_code;
21 } metadata;
22
23 void start_element(
24         GMarkupParseContext *context,
25         const gchar *element_name,
26         const gchar **attribute_names,
27         const gchar **attribute_values,
28         gpointer data,
29         GError **error)
30 {
31         metadata *md = (metadata*) data;
32         md->element_name = element_name;
33
34         if( !strcmp(element_name, "errorCode") ) {
35                 md->error = 1;
36                 md->error_message = "";
37                 md->error_code = "";
38         }
39
40         if( !strcmp(element_name, "ifindex") ) {
41                 md->ifid = "";
42                 md->title = "";
43                 md->author = "";
44                 md->firstpublished = "";
45         }
46 }
47
48 void text(
49         GMarkupParseContext *context,
50         const gchar *text,
51         gsize text_len,
52         gpointer data,
53         GError **error)
54 {
55         metadata *md = (metadata*) data;
56
57         if( !strcmp(md->element_name, "errorCode") ) {
58                 md->error_code = g_strndup(text, text_len);
59         }
60         else if( !strcmp(md->element_name, "errorMessage") ) {
61                 md->error_message = g_strndup(text, text_len);
62         }
63         else if( !strcmp(md->element_name, "ifid") ) {
64                 if( strlen(md->ifid) < text_len )
65                         md->ifid = g_strndup(text, text_len);
66         }
67         else if( !strcmp(md->element_name, "title") ) {
68                 if( strlen(md->title) < text_len )
69                         md->title = g_strndup(text, text_len);
70         }
71         else if( !strcmp(md->element_name, "author") ) {
72                 if( strlen(md->author) < text_len )
73                         md->author = g_strndup(text, text_len);
74         }
75         else if( !strcmp(md->element_name, "firstpublished") ) {
76                 if( strlen(md->firstpublished) < text_len )
77                         md->firstpublished = g_strndup(text, text_len);
78         }
79 }
80
81 void end_element(
82         GMarkupParseContext *context,
83         const gchar *element_name,
84         gpointer data,
85         GError **error)
86 {
87         if( !strcmp(element_name, "ifindex") ) {
88                 metadata *md = (metadata*) data;
89                 printf("IFID: %s\nTitle: %s\nAuthor: %s\nFirst published: %s\n", md->ifid, md->title, md->author, md->firstpublished);
90         }
91 }
92
93 /*
94  * run a non SELECT command and stops if an error occurs
95  */
96 void
97 run_sql_non_select(GdaConnection *cnc, const gchar *sql)
98 {
99         GdaStatement *stmt;
100         GError *error = NULL;
101         gint nrows;
102         const gchar *remain;
103         GdaSqlParser *parser;
104
105         parser = g_object_get_data(G_OBJECT(cnc), "parser");
106         stmt = gda_sql_parser_parse_string(parser, sql, &remain, &error);
107         if(remain) 
108                 g_print ("REMAINS: %s\n", remain);
109
110         nrows = gda_connection_statement_execute_non_select(cnc, stmt, NULL, NULL, &error);
111         if(nrows == -1)
112                 g_error("NON SELECT error: %s\n", error && error->message ? error->message : "no detail");
113         g_object_unref(stmt);
114 }
115
116 int main(int argc, char **argv) {
117         GError *err = NULL;
118         metadata data;
119         data.error = 0;
120
121         if(argc < 2) {
122                 fprintf(stderr, "Usage: %s <story file>\n", argv[0]);
123                 return 1;
124         }
125
126         g_type_init();
127
128         babel_init(argv[1]);
129         int len = babel_treaty(GET_STORY_FILE_METADATA_EXTENT_SEL, NULL, 0);
130         gchar *ifiction;
131         if(len) {
132                 printf("Metadata found in file.\n");
133                 gchar *buffer = malloc(len * sizeof(gchar));
134                 babel_treaty(GET_STORY_FILE_METADATA_SEL, buffer, len);
135                 ifiction = g_strndup(buffer, len);
136                 g_free(buffer);
137         } else {
138                 printf("No metadata found in file, performing IFDB lookup.\n");
139                 gchar *ifid = malloc(TREATY_MINIMUM_EXTENT * sizeof(gchar));
140                 if( !babel_treaty(GET_STORY_FILE_IFID_SEL, ifid, TREATY_MINIMUM_EXTENT) ) {
141                         fprintf(stderr, "Unable to create an IFID (A serious problem occurred while loading the file).\n");
142                         babel_release();
143                         return 1;
144                 }
145                 printf("Looking up IFID: %s.\n", ifid);
146                 babel_release();
147
148                 SoupSession *session = soup_session_async_new();
149                 char *uri_string = g_strconcat("http://ifdb.tads.org/viewgame?ifiction&ifid=", ifid, NULL);
150                 SoupMessage *message = soup_message_new("GET", uri_string);
151                 g_free(uri_string);
152                 soup_message_headers_append(message->request_headers, "Connection", "close");
153                 if(soup_session_send_message(session, message) != 200)
154                         g_printerr("ERROR: did not get HTTP status 200\n");
155                 ifiction = g_strndup(message->response_body->data, message->response_body->length);
156                 g_object_unref(message);
157                 g_object_unref(session);
158         }
159
160         ifiction = g_strchomp(ifiction);
161
162         GMarkupParser xml_parser = {start_element, end_element, text, NULL, NULL};
163         GMarkupParseContext *context = g_markup_parse_context_new(&xml_parser, 0, &data, NULL);
164
165         if( g_markup_parse_context_parse(context, ifiction, strlen(ifiction), &err) == FALSE ) {
166                 fprintf(stderr, "Metadata parse failed: %s\n", err->message);
167         }
168
169         g_markup_parse_context_free(context);
170         g_free(ifiction);
171
172         babel_release();
173
174         // Check for errors
175         if(data.error) {
176                 fprintf(stderr, "ERROR %s: %s\n", data.error_code, data.error_message);
177                 return 1;
178         }
179
180         // Open DB connection
181         GdaConnection *cnc;
182         GdaSqlParser *sql_parser;
183
184         gda_init();
185         cnc = gda_connection_open_from_string("SQLite", "DB_DIR=.;DB_NAME=library", NULL, GDA_CONNECTION_OPTIONS_NONE, &err);
186         if(!cnc) {
187                 fprintf(stderr, "Could not open connection to SQLite database in library.db file: %s\n", err && err->message ? err->message : "No details");
188                 return 1;
189         }
190
191         sql_parser = gda_connection_create_parser(cnc);
192         if(!sql_parser) // cnc does not provide its own parser, use default one
193                 sql_parser = gda_sql_parser_new();
194
195         g_object_set_data_full(G_OBJECT(cnc), "parser", sql_parser, g_object_unref);
196         
197         // Create stories table
198         //run_sql_non_select(cnc, "DROP TABLE IF EXISTS stories");
199         run_sql_non_select(cnc, "CREATE TABLE IF NOT EXISTS stories (ifid text not null primary key, title text, author text, firstpublished text)");
200
201         // Populate the table
202         GValue *v1, *v2, *v3, *v4;
203         v1 = gda_value_new_from_string(data.ifid, G_TYPE_STRING);
204         v2 = gda_value_new_from_string(data.title, G_TYPE_STRING);
205         v3 = gda_value_new_from_string(data.author, G_TYPE_STRING);
206         v4 = gda_value_new_from_string(data.firstpublished, G_TYPE_STRING);
207
208         if( !gda_insert_row_into_table(cnc, "stories", &err, "ifid", v1, "title", v2, "author", v3, "firstpublished", v4, NULL) ) {
209                 g_warning("Could not INSERT data into the 'stories' table: %s\n", err && err->message ? err->message : "No details");
210         }
211
212         gda_value_free(v1);
213         gda_value_free(v2);
214         gda_value_free(v3);
215         gda_value_free(v4);
216
217         // Dump the table contents
218         GdaDataModel *data_model;
219         GdaStatement *stmt = gda_sql_parser_parse_string(sql_parser, "SELECT * FROM stories", NULL, NULL);
220         data_model = gda_connection_statement_execute_select(cnc, stmt, NULL, &err);
221         if(!data_model)
222                 g_error("Could not get the contents of the 'stories' table: %s\n", err && err->message ? err->message : "No details");
223         printf("Dumping library table:\n");
224         gda_data_model_dump(data_model, stdout);
225
226         g_object_unref(stmt);
227         g_object_unref(data_model);
228
229         gda_connection_close(cnc);
230         return 0;
231 }