Updated Spanish translation
[anjuta-git-plugin.git] / plugins / symbol-db / symbol-db-engine.c
blobf0507a1368b72c68a529e4e635d57c61f168170d
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta
4 * Copyright (C) Massimo Cora' 2007 <maxcvs@email.it>
5 *
6 * anjuta is free software.
7 *
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
11 * any later version.
13 * anjuta is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with anjuta. If not, write to:
20 * The Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor
22 * Boston, MA 02110-1301, USA.
27 interesting queries:
29 ------------------------
30 * get all namespaces.
31 select symbol.name from symbol join sym_kind on symbol.kind_id =
32 sym_kind.sym_kind_id where sym_kind.kind_name = "namespace";
34 ------------------------
35 * get all symbols_id which scope is under all namespaces' ones
36 select * from symbol where scope_id in (select symbol.scope_definition_id
37 from symbol join sym_kind on symbol.kind_id = sym_kind.sym_kind_id where
38 sym_kind.kind_name = "namespace");
40 ------------------------
41 * get all symbols which have a scope_id of symbol X. X is a symbol of kind namespace,
42 class, struct etc. Symbol X can be retrieved by something like
43 select * from symbol join sym_type on symbol.type_id = sym_type.type_id where
44 symbol.name = "First" and sym_type.type = "namespace";
45 our query is:
46 select * from symbol where scope_id = ;
47 at the end we have:
49 select * from symbol where scope_id = (select scope_definition_id from symbol join
50 sym_type on symbol.type_id = sym_type.type_id where symbol.name =
51 "First" and sym_type.type = "namespace");
54 ------------------------
55 * get a symbol by its name and type. In this case we want to search for the
56 class Fourth_2_class
57 select * from symbol join sym_type on symbol.type_id = sym_type.type_id where
58 symbol.name = "Fourth_2_class" and sym_type.type = "class";
60 sqlite> select * from symbol join sym_kind on symbol.kind_id = sym_kind.sym_kind_id
61 join scope on scope.scope_id = symbol.scope_id
62 join sym_type on sym_type.type_id = scope.type_id
63 where symbol.name = "Fourth_2_class"
64 and sym_kind.kind_name = "class"
65 and scope = "Fourth"
66 and sym_type.type = "namespace";
68 183|13|Fourth_2_class|52|0||140|137|175|8|-1|-1|0|8|class|137|Fourth|172|172|namespace|Fourth
70 //// alternativa ////
71 = get the *derived symbol*
72 select * from symbol
73 join sym_kind on symbol.kind_id = sym_kind.sym_kind_id
74 where symbol.name = "Fourth_2_class"
75 and sym_kind.kind_name = "class"
76 and symbol.scope_id in (select scope.scope_id from scope
77 join sym_type on scope.type_id = sym_type.type_id
78 where sym_type.type = 'namespace'
79 and sym_type.type_name = 'Fourth');
81 query that get the symbol's parent classes
83 select symbol_id_base, symbol.name from heritage
84 join symbol on heritage.symbol_id_base = symbol.symbol_id
85 where symbol_id_derived = (
86 select symbol_id from symbol
87 join sym_kind on symbol.kind_id = sym_kind.sym_kind_id
88 where symbol.name = "Fourth_2_class"
89 and sym_kind.kind_name = "class"
90 and symbol.scope_id in (
91 select scope.scope_id from scope
92 join sym_type on scope.type_id = sym_type.type_id
93 where sym_type.type = 'namespace'
94 and sym_type.type_name = 'Fourth'
99 182|Fourth_1_class
104 #include <time.h>
105 #include <unistd.h>
106 #include <sys/types.h>
107 #include <sys/mman.h>
108 #include <signal.h>
109 #include <fcntl.h> /* For O_* constants */
110 #include <string.h>
112 #include <libgnomevfs/gnome-vfs.h>
113 #include <libanjuta/anjuta-debug.h>
114 #include <libanjuta/anjuta-launcher.h>
115 #include <libgda/libgda.h>
116 #include "readtags.h"
117 #include "symbol-db-engine.h"
118 #include "symbol-db-engine-iterator.h"
120 /* file should be specified without the ".db" extension. */
121 #define ANJUTA_DB_FILE ".anjuta_sym_db"
123 #define TABLES_SQL ANJUTA_DATA_DIR"/tables.sql"
125 #define CTAGS_MARKER "#_#\n"
127 // FIXME: detect it by prefs
128 #define CTAGS_PATH "/usr/bin/ctags"
131 enum {
132 DO_UPDATE_SYMS = 1,
133 DONT_UPDATE_SYMS,
134 DONT_FAKE_UPDATE_SYMS,
135 END_UPDATE_GROUP_SYMS
138 typedef enum
140 PREP_QUERY_WORKSPACE_NEW = 0,
141 PREP_QUERY_GET_WORKSPACE_ID_BY_UNIQUE_NAME,
142 PREP_QUERY_PROJECT_NEW,
143 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME,
144 PREP_QUERY_UPDATE_PROJECT_ANALIZE_TIME,
145 PREP_QUERY_FILE_NEW,
146 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME,
147 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_NAME,
148 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_ID,
149 PREP_QUERY_UPDATE_FILE_ANALIZE_TIME,
150 PREP_QUERY_LANGUAGE_NEW,
151 PREP_QUERY_GET_LANGUAGE_ID_BY_UNIQUE_NAME,
152 PREP_QUERY_SYM_TYPE_NEW,
153 PREP_QUERY_GET_SYM_TYPE_ID,
154 PREP_QUERY_SYM_KIND_NEW,
155 PREP_QUERY_GET_SYM_KIND_BY_UNIQUE_NAME,
156 PREP_QUERY_SYM_ACCESS_NEW,
157 PREP_QUERY_GET_SYM_ACCESS_BY_UNIQUE_NAME,
158 PREP_QUERY_SYM_IMPLEMENTATION_NEW,
159 PREP_QUERY_GET_SYM_IMPLEMENTATION_BY_UNIQUE_NAME,
160 PREP_QUERY_HERITAGE_NEW,
161 PREP_QUERY_SCOPE_NEW,
162 PREP_QUERY_GET_SCOPE_ID,
163 PREP_QUERY_TMP_HERITAGE_NEW,
164 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE,
165 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE_WITH_INHERITS,
166 PREP_QUERY_TMP_HERITAGE_DELETE_ALL,
167 PREP_QUERY_SYMBOL_NEW,
168 PREP_QUERY_GET_SYMBOL_SCOPE_DEFINITION_ID,
169 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME,
170 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME_AND_NAMESPACE,
171 PREP_QUERY_UPDATE_SYMBOL_SCOPE_ID,
172 PREP_QUERY_GET_SYMBOL_ID_BY_UNIQUE_INDEX_KEY,
173 PREP_QUERY_UPDATE_SYMBOL_ALL,
174 PREP_QUERY_GET_REMOVED_IDS,
175 PREP_QUERY_TMP_REMOVED_DELETE_ALL,
176 PREP_QUERY_COUNT
177 } query_type;
180 typedef struct _query_node
182 query_type query_id;
183 gchar *query_str;
184 GdaQuery *query;
186 } query_node;
189 /* *MUST* respect query_type enum order. */
190 /* FIXME: Libgda does not yet support 'LIMIT' keyword. This can be used to
191 * speed up some select(s). Please upgrade them as soon as the library support
192 * it.
194 static query_node query_list[PREP_QUERY_COUNT] = {
195 /* -- workspace -- */
197 PREP_QUERY_WORKSPACE_NEW,
198 "INSERT INTO workspace (workspace_name, analize_time) "
199 "VALUES (## /* name:'wsname' type:gchararray */,"
200 "datetime ('now', 'localtime'))",
201 NULL
204 PREP_QUERY_GET_WORKSPACE_ID_BY_UNIQUE_NAME,
205 "SELECT workspace_id FROM workspace WHERE workspace_name = ## /* name:'wsname' "
206 "type:gchararray */",
207 NULL
209 /* -- project -- */
211 PREP_QUERY_PROJECT_NEW,
212 "INSERT INTO project (project_name, wrkspace_id, analize_time) "
213 "VALUES (## /* name:'prjname' type:gchararray */,"
214 "## /* name:'wsid' type:gint */," "datetime ('now', 'localtime'))",
215 NULL
218 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME,
219 "SELECT project_id FROM project WHERE project_name = ## /* name:'prjname' "
220 "type:gchararray */",
221 NULL
224 PREP_QUERY_UPDATE_PROJECT_ANALIZE_TIME,
225 "UPDATE project SET analize_time = datetime('now', 'localtime') WHERE "
226 "project_name = ## /* name:'prjname' type:gchararray */",
227 NULL
229 /* -- file -- */
231 PREP_QUERY_FILE_NEW,
232 "INSERT INTO file (file_path, prj_id, lang_id, analize_time) VALUES ("
233 "## /* name:'filepath' type:gchararray */, ## /* name:'prjid' "
234 "type:gint */, ## /* name:'langid' type:gint */, "
235 "datetime ('now', 'localtime'))",
236 NULL
239 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME,
240 "SELECT file_id FROM file WHERE file_path = ## /* name:'filepath' "
241 "type:gchararray */",
242 NULL
245 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_NAME,
246 "SELECT * FROM file WHERE prj_id = (SELECT project_id FROM project "
247 "WHERE project_name = ## /* name:'prjname' type:gchararray */)",
248 NULL
251 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_ID,
252 "SELECT * FROM file WHERE prj_id = ## /* name:'prjid' type:gint */",
254 "SELECT * FROM file JOIN project on project_id = prj_id WHERE "\
255 "project.name = ## /* name:'prjname' type:gchararray * /",
257 NULL
260 PREP_QUERY_UPDATE_FILE_ANALIZE_TIME,
261 "UPDATE file SET analize_time = datetime('now', 'localtime') WHERE "
262 "file_path = ## /* name:'filepath' type:gchararray */",
263 NULL},
264 /* -- language -- */
266 PREP_QUERY_LANGUAGE_NEW,
267 "INSERT INTO language (language_name) VALUES (## /* name:'langname' "
268 "type:gchararray */)",
269 NULL
272 PREP_QUERY_GET_LANGUAGE_ID_BY_UNIQUE_NAME,
273 "SELECT language_id FROM language WHERE language_name = ## /* name:'langname' "
274 "type:gchararray */",
275 NULL
277 /* -- sym type -- */
279 PREP_QUERY_SYM_TYPE_NEW,
280 "INSERT INTO sym_type (type, type_name) VALUES (## /* name:'type' "
281 "type:gchararray */, ## /* name:'typename' type:gchararray */)",
282 NULL
285 PREP_QUERY_GET_SYM_TYPE_ID,
286 "SELECT type_id FROM sym_type WHERE type = ## /* name:'type' "
287 "type:gchararray */ AND type_name = ## /* name:'typename' "
288 "type:gchararray */",
289 NULL
291 /* -- sym kind -- */
293 PREP_QUERY_SYM_KIND_NEW,
294 "INSERT INTO sym_kind (kind_name) VALUES(## /* name:'kindname' "
295 "type:gchararray */)",
296 NULL
299 PREP_QUERY_GET_SYM_KIND_BY_UNIQUE_NAME,
300 "SELECT sym_kind_id FROM sym_kind WHERE kind_name = ## /* "
301 "name:'kindname' type:gchararray */",
302 NULL
304 /* -- sym access -- */
306 PREP_QUERY_SYM_ACCESS_NEW,
307 "INSERT INTO sym_access (access_name) VALUES(## /* name:'accesskind' "
308 "type:gchararray */)",
309 NULL
312 PREP_QUERY_GET_SYM_ACCESS_BY_UNIQUE_NAME,
313 "SELECT access_kind_id FROM sym_access WHERE access_name = ## /* "
314 "name:'accesskind' type:gchararray */",
315 NULL
317 /* -- sym implementation -- */
319 PREP_QUERY_SYM_IMPLEMENTATION_NEW,
320 "INSERT INTO sym_implementation (implementation_name) VALUES(## /* name:'implekind' "
321 "type:gchararray */)",
322 NULL
325 PREP_QUERY_GET_SYM_IMPLEMENTATION_BY_UNIQUE_NAME,
326 "SELECT sym_impl_id FROM sym_implementation WHERE kind = ## /* "
327 "name:'implekind' type:gchararray */",
328 NULL
330 /* -- heritage -- */
332 PREP_QUERY_HERITAGE_NEW,
333 "INSERT INTO heritage (symbol_id_base, symbol_id_derived) VALUES(## /* "
334 "name:'symbase' type:gint */, ## /* name:'symderived' type:gint */)",
335 NULL
337 /* -- scope -- */
339 PREP_QUERY_SCOPE_NEW,
340 "INSERT INTO scope (scope, type_id) VALUES(## /* name:'scope' "
341 "type:gchararray */, ## /* name:'typeid' type:gint */)",
342 NULL
345 PREP_QUERY_GET_SCOPE_ID,
346 "SELECT scope_id FROM scope WHERE scope = ## /* name:'scope' "
347 "type:gchararray */ AND type_id = ## /* name:'typeid' type:gint */",
348 NULL
350 /* -- tmp heritage -- */
352 PREP_QUERY_TMP_HERITAGE_NEW,
353 "INSERT INTO __tmp_heritage_scope (symbol_referer_id, field_inherits, "
354 "field_struct, field_typeref, field_enum, field_union, "
355 "field_class, field_namespace) VALUES (## /* name:'symreferid' "
356 "type:gint */, ## /* name:'finherits' type:gchararray */, ## /* "
357 "name:'fstruct' type:gchararray */, ## /* name:'ftyperef' "
358 "type:gchararray */, ## /* name:'fenum' type:gchararray */, ## /* "
359 "name:'funion' type:gchararray */, ## /* name:'fclass' type:gchararray "
360 "*/, ## /* name:'fnamespace' type:gchararray */)",
361 NULL
364 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE,
365 "SELECT * FROM __tmp_heritage_scope",
366 NULL
369 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE_WITH_INHERITS,
370 "SELECT * FROM __tmp_heritage_scope WHERE field_inherits != ''",
371 NULL
374 PREP_QUERY_TMP_HERITAGE_DELETE_ALL,
375 "DELETE FROM __tmp_heritage_scope",
376 NULL
378 /* -- symbol -- */
380 PREP_QUERY_SYMBOL_NEW,
381 "INSERT INTO symbol (file_defined_id, name, file_position, "
382 "is_file_scope, signature, scope_definition_id, scope_id, type_id, "
383 "kind_id, access_kind_id, implementation_kind_id, update_flag) VALUES("
384 "## /* name:'filedefid' type:gint */, ## /* name:'name' "
385 "type:gchararray */, ## /* name:'fileposition' type:gint */, ## /* "
386 "name:'isfilescope' type:gint */, ## /* name:'signature' "
387 "type:gchararray */,## /* name:'scopedefinitionid' type:gint */, ## "
388 "/* name:'scopeid' type:gint */,## /* name:'typeid' type:gint */, ## "
389 "/* name:'kindid' type:gint */,## /* name:'accesskindid' type:gint */, "
390 "## /* name:'implementationkindid' type:gint */, ## /* "
391 "name:'updateflag' type:gint */)",
392 NULL
395 PREP_QUERY_GET_SYMBOL_SCOPE_DEFINITION_ID,
396 "SELECT scope_definition_id FROM symbol JOIN sym_type ON symbol.type_id"
397 "= sym_type.type_id WHERE sym_type.type = ## /* name:'tokenname' "
398 "type:gchararray */ AND sym_type.type_name = ## /* name:'objectname' "
399 "type:gchararray */",
400 NULL
403 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME,
404 "SELECT symbol_id FROM symbol JOIN sym_type ON symbol.type_id = "
405 "sym_type.type_id WHERE scope_id=0 AND sym_type.type='class' AND "
406 "name = ## /* name:'klassname' type:gchararray */",
407 NULL
410 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME_AND_NAMESPACE,
411 "SELECT symbol_id FROM symbol JOIN scope ON symbol.scope_id = "
412 "scope.scope_id JOIN sym_type ON scope.type_id = sym_type.type_id "
413 "WHERE symbol.name = /* name:'klassname' type:gchararray */ AND "
414 "scope.scope = /* name:'namespacename' type:gchararray */ AND "
415 "sym_type.type='namespace'",
416 NULL
419 PREP_QUERY_UPDATE_SYMBOL_SCOPE_ID,
420 "UPDATE symbol SET scope_id = ## /* name:'scopeid' type:gint */ "
421 "WHERE symbol_id = ## /* name:'symbolid' type:gint */",
422 NULL
425 PREP_QUERY_GET_SYMBOL_ID_BY_UNIQUE_INDEX_KEY,
426 "SELECT symbol_id FROM symbol WHERE name = ## /* name:'symname' "
427 "type:gchararray */ AND file_defined_id = ## /* name:'filedefid' "
428 "type:gint */ AND type_id = ## /* name:'typeid' type:gint */",
429 NULL
432 PREP_QUERY_UPDATE_SYMBOL_ALL,
433 "UPDATE symbol SET is_file_scope = ## /* name:'isfilescope' type:gint "
434 "*/, signature = ## /* name:'signature' type:gchararray */, "
435 "scope_definition_id = ## /* name:'scopedefinitionid' type:gint */, "
436 "scope_id = ## /* name:'scopeid' type:gint */, kind_id = "
437 "## /* name:'kindid' type:gint */, access_kind_id = ## /* name:"
438 "'accesskindid' type:gint */, implementation_kind_id = ## /* name:"
439 "'implementationkindid' type:gint */, update_flag = ## /* name:"
440 "'updateflag' type:gint */ WHERE symbol_id = ## /* name:'symbolid' type:"
441 "gint */",
442 NULL
444 /* -- tmp_removed -- */
446 PREP_QUERY_GET_REMOVED_IDS,
447 "SELECT symbol_removed_id FROM __tmp_removed",
448 NULL
451 PREP_QUERY_TMP_REMOVED_DELETE_ALL,
452 "DELETE FROM __tmp_removed",
453 NULL
458 /* this is a special case which is not doable with a prepared query. */
459 static GdaCommand *last_insert_id_cmd = NULL;
461 typedef void (SymbolDBEngineCallback) (SymbolDBEngine * dbe,
462 gpointer user_data);
464 enum
466 SCAN_END,
467 SYMBOL_INSERTED,
468 SYMBOL_UPDATED,
469 SYMBOL_REMOVED,
470 LAST_SIGNAL
473 static unsigned int signals[LAST_SIGNAL] = { 0 };
476 struct _SymbolDBEnginePriv
478 GdaConnection *db_connection;
479 GdaClient *gda_client;
480 GdaDict *dict;
481 gchar *dsn_name;
482 gchar *project_name;
483 gchar *data_source;
485 GAsyncQueue *scan_queue;
487 GAsyncQueue *updated_symbols_id;
488 GAsyncQueue *inserted_symbols_id;
490 gchar *shared_mem_str;
491 FILE *shared_mem_file;
492 gint shared_mem_fd;
493 AnjutaLauncher *ctags_launcher;
494 gboolean scanning_status;
495 gboolean force_sym_update;
498 static GObjectClass *parent_class = NULL;
501 static void sdb_engine_second_pass_do (SymbolDBEngine * dbe);
502 static gint
503 sdb_engine_add_new_symbol (SymbolDBEngine * dbe, tagEntry * tag_entry,
504 gchar * base_prj_path, gchar * fake_file,
505 gboolean sym_update);
509 * Use this as little as you can. Prepared statements are quicker.
511 static void inline
512 sdb_engine_execute_non_select_sql (SymbolDBEngine * dbe, const gchar * buffer)
514 SymbolDBEnginePriv *priv;
515 GdaCommand *command;
517 priv = dbe->priv;
519 command = gda_command_new (buffer, GDA_COMMAND_TYPE_SQL,
520 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
521 gda_connection_execute_non_select_command (priv->db_connection,
522 command, NULL, NULL);
523 gda_command_free (command);
527 * Will test the opened project within the dbe plugin and the passed one.
529 gboolean inline
530 symbol_db_engine_is_project_opened (SymbolDBEngine *dbe, const gchar* project_name)
532 SymbolDBEnginePriv *priv;
534 g_return_val_if_fail (dbe != NULL, FALSE);
535 priv = dbe->priv;
537 if (priv->project_name == NULL)
538 return FALSE;
540 return strcmp (project_name, priv->project_name) == 0 ? TRUE : FALSE;
544 * Use a proxy to return an already present or a fresh new prepared query
545 * from static 'query_list'. We should perform actions in the fastest way, because
546 * these queries are time-critical.
549 static inline const GdaQuery *
550 sdb_engine_get_query_by_id (SymbolDBEngine * dbe, query_type query_id)
552 query_node *node;
553 SymbolDBEnginePriv *priv;
555 priv = dbe->priv;
557 /* no way: if connection is NULL we will break here. There must be
558 * a connection established to db before using this function */
559 g_return_val_if_fail (priv->db_connection != NULL, NULL);
561 node = &query_list[query_id];
563 /* check for a null dict into priv struct */
564 if (priv->dict == NULL)
566 priv->dict = gda_dict_new ();
567 gda_dict_set_connection (priv->dict, priv->db_connection);
570 if (node->query == NULL)
572 DEBUG_PRINT ("generating new query.... %d", query_id);
573 /* create a new GdaQuery */
574 node->query =
575 gda_query_new_from_sql (priv->dict, node->query_str, NULL);
578 return node->query;
581 static inline gint
582 sdb_engine_get_last_insert_id (SymbolDBEngine * dbe)
584 GdaDataModel *data;
585 const GValue *num;
586 gint table_id;
587 SymbolDBEnginePriv *priv;
589 priv = dbe->priv;
591 /* check whether we have already initialized it or not. */
592 if (last_insert_id_cmd == NULL)
594 DEBUG_PRINT ("creating new command...");
595 last_insert_id_cmd = gda_command_new ("SELECT last_insert_rowid()",
596 GDA_COMMAND_TYPE_SQL,
597 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
600 if ((data = gda_connection_execute_select_command (priv->db_connection,
601 last_insert_id_cmd, NULL,
602 NULL)) == NULL
603 || gda_data_model_get_n_rows (data) <= 0)
605 return -1;
608 num = gda_data_model_get_value_at (data, 0, 0);
609 if (G_VALUE_HOLDS (num, G_TYPE_INT))
610 table_id = g_value_get_int (num);
611 else
612 return -1;
614 g_object_unref (data);
615 return table_id;
619 * Clear the static cached queries data. You should call this function when closing/
620 * destroying SymbolDBEngine object.
621 * priv->dict is also destroyed.
623 static void
624 sdb_engine_free_cached_queries (SymbolDBEngine * dbe)
626 gint i;
627 query_node *node;
628 SymbolDBEnginePriv *priv;
630 priv = dbe->priv;
632 for (i = 0; i < PREP_QUERY_COUNT; i++)
634 node = &query_list[i];
636 if (node->query != NULL)
638 g_object_unref ((gpointer) node->query);
639 node->query = NULL;
643 /* destroys also dict */
644 g_object_unref (priv->dict);
647 static gboolean
648 sdb_engine_disconnect_from_db (SymbolDBEngine * dbe)
650 SymbolDBEnginePriv *priv;
652 g_return_val_if_fail (dbe != NULL, FALSE);
653 priv = dbe->priv;
655 if (priv->gda_client)
657 gda_client_close_all_connections (priv->gda_client);
658 g_object_unref (priv->gda_client);
660 priv->gda_client = NULL;
661 priv->db_connection = NULL;
663 if (priv->data_source)
665 g_free (priv->data_source);
666 priv->data_source = NULL;
669 if (priv->dsn_name)
671 g_free (priv->dsn_name);
672 priv->dsn_name = NULL;
675 if (priv->dict)
677 g_object_unref (priv->dict);
678 priv->dict = NULL;
682 return TRUE;
686 * If base_prj_path != NULL then fake_file will not be parsed. Else
687 * if fake_file is != NULL we claim and assert that tags contents which are
688 * scanned belong to the fake_file in the project.
689 * More: the fake_file refers to just one single file and cannot be used
690 * for multiple fake_files.
692 static void
693 sdb_engine_populate_db_by_tags (SymbolDBEngine * dbe, FILE* fd,
694 gchar * base_prj_path, gchar * fake_file_on_db,
695 gboolean force_sym_update)
697 tagFile *tag_file;
698 tagFileInfo tag_file_info;
699 tagEntry tag_entry;
701 SymbolDBEnginePriv *priv;
703 g_return_if_fail (dbe != NULL);
705 priv = dbe->priv;
707 g_return_if_fail (priv->db_connection != NULL);
708 g_return_if_fail (fd != NULL);
710 if (priv->updated_symbols_id == NULL)
711 priv->updated_symbols_id = g_async_queue_new ();
713 if (priv->inserted_symbols_id == NULL)
714 priv->inserted_symbols_id = g_async_queue_new ();
716 DEBUG_PRINT ("sdb_engine_populate_db_by_tags ()");
717 if ((tag_file = tagsOpen_1 (fd, &tag_file_info)) == NULL)
718 g_warning ("error in opening ctags file");
720 gda_connection_begin_transaction (priv->db_connection, "fixme", 0, NULL);
722 while (tagsNext (tag_file, &tag_entry) != TagFailure)
724 sdb_engine_add_new_symbol (dbe, &tag_entry, fake_file_on_db == NULL ?
725 base_prj_path : NULL, fake_file_on_db,
726 force_sym_update);
729 gda_connection_commit_transaction (priv->db_connection, "fixme", NULL);
732 static void
733 sdb_engine_ctags_output_callback_1 (AnjutaLauncher * launcher,
734 AnjutaLauncherOutputType output_type,
735 const gchar * chars, gpointer user_data)
737 gint i;
738 gint len_chars;
739 gint remaining_chars;
740 gint len_marker;
741 gchar *chars_ptr;
742 SymbolDBEnginePriv *priv;
743 SymbolDBEngine *dbe;
745 g_return_if_fail (user_data != NULL);
746 g_return_if_fail (chars != NULL);
748 dbe = (SymbolDBEngine*)user_data;
749 priv = dbe->priv;
751 chars_ptr = (gchar*)chars;
753 remaining_chars = len_chars = strlen (chars);
754 len_marker = strlen (CTAGS_MARKER);
756 /* DEBUG_PRINT ("gotta %s", chars_ptr);*/
758 if ( len_chars >= len_marker )
760 gchar *marker_ptr = NULL;
761 gint tmp_str_length = 0;
763 /* is it an end file marker? */
764 marker_ptr = strstr (chars_ptr, CTAGS_MARKER);
766 do {
767 if (marker_ptr != NULL)
769 gint scan_flag;
770 gchar *real_file;
771 DEBUG_PRINT ("found marker!");
773 /* set the length of the string parsed */
774 tmp_str_length = marker_ptr - chars_ptr;
776 /*DEBUG_PRINT ("program output [new version]: ==>%s<==", chars_ptr);*/
777 /* write to shm_file all the chars_ptr received without the marker ones */
778 fwrite (chars_ptr, sizeof(gchar), tmp_str_length, priv->shared_mem_file);
780 chars_ptr = marker_ptr + len_marker;
781 remaining_chars -= (tmp_str_length + len_marker);
782 fflush (priv->shared_mem_file);
784 /* get the scan flag from the queue. We need it to know whether
785 * an update of symbols must be done or not */
786 scan_flag = (int)g_async_queue_try_pop (priv->scan_queue);
787 real_file = g_async_queue_try_pop (priv->scan_queue);
789 /* and now call the populating function */
790 sdb_engine_populate_db_by_tags (dbe, priv->shared_mem_file,
791 priv->data_source,
792 (int)real_file == DONT_FAKE_UPDATE_SYMS ? NULL : real_file,
793 scan_flag == DO_UPDATE_SYMS ? TRUE : FALSE);
795 /* don't forget to free the real_life, if it's a char */
796 if ((int)real_file != DONT_FAKE_UPDATE_SYMS)
797 g_free (real_file);
799 /* check also if, together with an end file marker, we have an
800 * end group-of-files end marker.
802 if ((strcmp (marker_ptr + len_marker, CTAGS_MARKER) == 0) ||
803 ftell (priv->shared_mem_file) <= 0)
805 gint tmp_inserted;
806 gint tmp_updated;
807 int j;
809 /* proceed with second passes */
810 DEBUG_PRINT ("FOUND end-of-group-files marker.\n"
811 "go on with sdb_engine_second_pass_do ()");
812 sdb_engine_second_pass_do (dbe);
814 chars_ptr += len_marker;
815 remaining_chars -= len_marker;
818 /* Here we are. It's the right time to notify the listeners
819 * about out fresh new inserted/updated symbols...
820 * Go on by emitting them.
822 while ((tmp_inserted = (int)
823 g_async_queue_try_pop (priv->inserted_symbols_id)) > 0)
825 g_signal_emit (dbe, signals[SYMBOL_INSERTED], 0, tmp_inserted);
828 while ((tmp_updated = (int)
829 g_async_queue_try_pop (priv->updated_symbols_id)) > 0)
831 g_signal_emit (dbe, signals[SYMBOL_UPDATED], 0, tmp_updated);
834 /* emit signal. The end of files-group can be cannot be
835 * determined by the caller. This is the only way.
837 DEBUG_PRINT ("EMITTING scan-end");
838 g_signal_emit (dbe, signals[SCAN_END], 0);
841 /* truncate the file to 0 length */
842 ftruncate (priv->shared_mem_fd, 0);
844 else
846 /* marker_ptr is NULL here. We should then exit the loop. */
847 /* write to shm_file all the chars received */
848 fwrite (chars_ptr, sizeof(gchar), remaining_chars,
849 priv->shared_mem_file);
851 fflush (priv->shared_mem_file);
852 break;
855 /* found out a new marker */
856 marker_ptr = strstr (marker_ptr + len_marker, CTAGS_MARKER);
857 } while (remaining_chars + len_marker < len_chars);
859 else
861 DEBUG_PRINT ("no len_chars > len_marker");
865 static void
866 on_scan_files_end_1 (AnjutaLauncher * launcher, int child_pid,
867 int exit_status, gulong time_taken_in_seconds,
868 gpointer data)
870 DEBUG_PRINT ("ctags ended");
874 /* Scans with ctags and produce an output 'tags' file [shared memory file]
875 * containing language symbols. This function will call ctags
876 * executale and then sdb_engine_populate_db_by_tags () when it'll detect some
877 * output.
878 * Please note the files_list/real_files_list parameter:
879 * this version of sdb_engine_scan_files_1 () let you scan for text buffer(s) that
880 * will be claimed as buffers for the real files.
881 * 1. simple mode: files_list represents the real files on disk and so we don't
882 * need real_files_list, which will be NULL.
883 * 2. advanced mode: files_list represents temporary flushing of buffers on disk, i.e.
884 * /tmp/anjuta_XYZ.cxx. real_files_list is the representation of those files on
885 * database. On the above example we can have anjuta_XYZ.cxx mapped as /src/main.c
886 * on db. In this mode files_list and real_files_list must have the same size.
889 /* server mode version */
890 static gboolean
891 sdb_engine_scan_files_1 (SymbolDBEngine * dbe, const GPtrArray * files_list,
892 const GPtrArray *real_files_list, gboolean symbols_update)
894 SymbolDBEnginePriv *priv;
895 gint i;
897 g_return_val_if_fail (dbe != NULL, FALSE);
898 g_return_val_if_fail (files_list != NULL, FALSE);
900 if (files_list->len == 0)
901 return FALSE;
903 /* start process in server mode */
904 priv = dbe->priv;
906 if (real_files_list != NULL && (files_list->len != real_files_list->len))
908 g_warning ("no matched size between real_files_list and files_list");
909 return FALSE;
912 /* if ctags_launcher isn't initialized, then do it now. */
913 if (priv->ctags_launcher == NULL)
915 gchar *exe_string;
917 DEBUG_PRINT ("creating anjuta_launcher");
918 priv->ctags_launcher = anjuta_launcher_new ();
920 g_signal_connect (G_OBJECT (priv->ctags_launcher), "child-exited",
921 G_CALLBACK (on_scan_files_end_1), NULL);
923 exe_string = g_strdup_printf ("%s --fields=afmiKlnsStz "
924 "--filter=yes --filter-terminator='"CTAGS_MARKER"'",
925 CTAGS_PATH);
927 anjuta_launcher_execute (priv->ctags_launcher,
928 exe_string, sdb_engine_ctags_output_callback_1,
929 dbe);
930 g_free (exe_string);
933 /* what about the scan_queue? is it initialized? It will contain mainly
934 * ints that refers to the force_update status.
936 if (priv->scan_queue == NULL)
938 priv->scan_queue = g_async_queue_new ();
941 /* create the shared memory file */
942 if (priv->shared_mem_file == 0)
944 gchar *temp_file;
945 temp_file = g_strdup_printf ("/anjuta-%d_%ld.tags", getpid (),
946 time (NULL));
948 priv->shared_mem_str = temp_file;
950 if ((priv->shared_mem_fd =
951 shm_open (temp_file, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) < 0)
953 g_warning ("Error while trying to open a shared memory file. Be"
954 "sure to have /dev/shm mounted with tmpfs");
957 priv->shared_mem_file = fdopen (priv->shared_mem_fd, "a+b");
959 DEBUG_PRINT ("shared fd %d", priv->shared_mem_fd);
960 DEBUG_PRINT ("shared file %d", priv->shared_mem_file);
961 DEBUG_PRINT ("temp_file %s", temp_file);
963 /* no need to free temp_file. It will be freed on plugin finalize */
966 priv->scanning_status = TRUE;
968 DEBUG_PRINT ("files_list->len %d", files_list->len);
970 for (i = 0; i < files_list->len; i++)
972 gchar *node = (gchar *) g_ptr_array_index (files_list, i);
974 if (g_file_test (node, G_FILE_TEST_EXISTS) == FALSE)
976 g_warning ("File %s not scanned because it does not exist", node);
977 continue;
979 DEBUG_PRINT ("anjuta_launcher_send_stdin %s", node);
980 anjuta_launcher_send_stdin (priv->ctags_launcher, node);
981 anjuta_launcher_send_stdin (priv->ctags_launcher, "\n");
983 if (symbols_update == TRUE)
984 g_async_queue_push (priv->scan_queue, (gpointer) DO_UPDATE_SYMS);
985 else
986 g_async_queue_push (priv->scan_queue, (gpointer) DONT_UPDATE_SYMS);
988 /* don't forget to add the real_files if the caller provided a list for
989 * them! */
990 if (real_files_list != NULL)
992 g_async_queue_push (priv->scan_queue,
993 (gpointer)g_strdup (
994 g_ptr_array_index (real_files_list, i)));
996 else
998 /* else add a DONT_FAKE_UPDATE_SYMS marker, just to noty that this is
999 * not a fake file scan
1001 g_async_queue_push (priv->scan_queue, (gpointer) DONT_FAKE_UPDATE_SYMS);
1005 /* hack to let ctags output a marker. We will then process it into the
1006 * output callback function */
1007 anjuta_launcher_send_stdin (priv->ctags_launcher, "/dev/null\n");
1009 priv->scanning_status = FALSE;
1011 return TRUE;
1016 static void
1017 sdb_engine_init (SymbolDBEngine * object)
1019 SymbolDBEngine *sdbe;
1021 sdbe = SYMBOL_DB_ENGINE (object);
1022 sdbe->priv = g_new0 (SymbolDBEnginePriv, 1);
1024 /* initialize some priv data */
1025 sdbe->priv->gda_client = NULL;
1026 sdbe->priv->db_connection = NULL;
1027 sdbe->priv->dsn_name = NULL;
1028 sdbe->priv->project_name = NULL;
1029 sdbe->priv->data_source = NULL;
1031 sdbe->priv->scan_queue = NULL;
1032 sdbe->priv->updated_symbols_id = NULL;
1033 sdbe->priv->inserted_symbols_id = NULL;
1034 sdbe->priv->shared_mem_file = NULL;
1035 sdbe->priv->shared_mem_fd = 0;
1036 sdbe->priv->shared_mem_str = NULL;
1037 sdbe->priv->scanning_status = FALSE;
1038 sdbe->priv->force_sym_update = FALSE;
1040 /* Initialize gda library. */
1041 gda_init ("AnjutaGda", NULL, 0, NULL);
1043 /* create Anjuta Launcher instance. It will be used for tags parsing. */
1044 sdbe->priv->ctags_launcher = NULL;
1047 static void
1048 sdb_engine_finalize (GObject * object)
1050 SymbolDBEngine *dbe;
1051 SymbolDBEnginePriv *priv;
1053 dbe = SYMBOL_DB_ENGINE (object);
1054 priv = dbe->priv;
1056 sdb_engine_disconnect_from_db (dbe);
1058 if (priv->project_name)
1060 g_free (priv->project_name);
1063 if (priv->scan_queue)
1065 g_async_queue_unref (priv->scan_queue);
1066 priv->scan_queue = NULL;
1069 if (priv->updated_symbols_id)
1071 g_async_queue_unref (priv->updated_symbols_id);
1072 priv->updated_symbols_id = NULL;
1076 if (priv->inserted_symbols_id)
1078 g_async_queue_unref (priv->inserted_symbols_id);
1079 priv->inserted_symbols_id = NULL;
1082 if (priv->shared_mem_file)
1084 fclose (priv->shared_mem_file);
1085 priv->shared_mem_file = NULL;
1089 if (priv->shared_mem_str)
1091 shm_unlink (priv->shared_mem_str);
1092 g_free (priv->shared_mem_str);
1093 priv->shared_mem_str = NULL;
1096 if (priv->ctags_launcher)
1098 anjuta_launcher_signal (priv->ctags_launcher, SIGINT);
1099 g_object_unref (priv->ctags_launcher);
1102 G_OBJECT_CLASS (parent_class)->finalize (object);
1105 static void
1106 sdb_engine_class_init (SymbolDBEngineClass * klass)
1108 GObjectClass *object_class = G_OBJECT_CLASS (klass);
1109 parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
1111 object_class->finalize = sdb_engine_finalize;
1113 signals[SCAN_END]
1114 = g_signal_new ("scan-end",
1115 G_OBJECT_CLASS_TYPE (object_class),
1116 G_SIGNAL_RUN_FIRST,
1117 G_STRUCT_OFFSET (SymbolDBEngineClass, scan_end),
1118 NULL, NULL,
1119 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
1121 signals[SYMBOL_INSERTED]
1122 = g_signal_new ("symbol-inserted",
1123 G_OBJECT_CLASS_TYPE (object_class),
1124 G_SIGNAL_RUN_FIRST,
1125 G_STRUCT_OFFSET (SymbolDBEngineClass, symbol_inserted),
1126 NULL, NULL,
1127 g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
1129 G_TYPE_INT);
1131 signals[SYMBOL_UPDATED]
1132 = g_signal_new ("symbol-updated",
1133 G_OBJECT_CLASS_TYPE (object_class),
1134 G_SIGNAL_RUN_FIRST,
1135 G_STRUCT_OFFSET (SymbolDBEngineClass, symbol_updated),
1136 NULL, NULL,
1137 g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
1139 G_TYPE_INT);
1141 signals[SYMBOL_REMOVED]
1142 = g_signal_new ("symbol-removed",
1143 G_OBJECT_CLASS_TYPE (object_class),
1144 G_SIGNAL_RUN_FIRST,
1145 G_STRUCT_OFFSET (SymbolDBEngineClass, symbol_removed),
1146 NULL, NULL,
1147 g_cclosure_marshal_VOID__INT, G_TYPE_NONE,
1149 G_TYPE_INT);
1153 GType
1154 symbol_db_engine_get_type (void)
1156 static GType our_type = 0;
1158 if (our_type == 0)
1160 static const GTypeInfo our_info = {
1161 sizeof (SymbolDBEngineClass), /* class_size */
1162 (GBaseInitFunc) NULL, /* base_init */
1163 (GBaseFinalizeFunc) NULL, /* base_finalize */
1164 (GClassInitFunc) sdb_engine_class_init, /* class_init */
1165 (GClassFinalizeFunc) NULL, /* class_finalize */
1166 NULL /* class_data */ ,
1167 sizeof (SymbolDBEngine), /* instance_size */
1168 0, /* n_preallocs */
1169 (GInstanceInitFunc) sdb_engine_init, /* instance_init */
1170 NULL /* value_table */
1173 our_type = g_type_register_static (G_TYPE_OBJECT, "SymbolDBEngine",
1174 &our_info, 0);
1177 return our_type;
1180 SymbolDBEngine *
1181 symbol_db_engine_new (void)
1183 SymbolDBEngine *sdbe;
1185 sdbe = g_object_new (SYMBOL_TYPE_DB_ENGINE, NULL);
1186 return sdbe;
1189 /* Will create priv->db_connection, priv->gda_client.
1190 * Connect to database identified by data_source.
1191 * Usually data_source is defined also into priv. We let it here as parameter
1192 * because it is required and cannot be null.
1194 static gboolean
1195 sdb_engine_connect_to_db (SymbolDBEngine * dbe, const gchar * data_source)
1197 SymbolDBEnginePriv *priv;
1199 g_return_val_if_fail (dbe != NULL, FALSE);
1200 priv = dbe->priv;
1202 if (priv->db_connection != NULL)
1204 /* if it's the case that the connection isn't NULL, we
1205 * should notify the user
1206 * and return FALSE. It's his task to disconnect and retry to connect */
1207 g_warning ("connection is already established. Please disconnect "
1208 "and then try to reconnect.");
1209 return FALSE;
1212 /* create new client */
1213 priv->gda_client = gda_client_new ();
1215 /* establish a connection. If the sqlite file does not exist it will
1216 * be created
1218 priv->db_connection
1219 = gda_client_open_connection (priv->gda_client, data_source,
1220 "", "",
1221 GDA_CONNECTION_OPTIONS_READ_ONLY, NULL);
1223 if (!GDA_IS_CONNECTION (priv->db_connection))
1225 g_warning ("could not open connection to %s\n", data_source);
1226 return FALSE;
1229 g_message ("connected to database %s", data_source);
1230 return TRUE;
1235 * Creates required tables for the database to work.
1236 * @param tables_sql_file File containing sql code.
1238 static gboolean
1239 sdb_engine_create_db_tables (SymbolDBEngine * dbe, gchar * tables_sql_file)
1241 GError *err;
1242 GdaCommand *command;
1243 SymbolDBEnginePriv *priv;
1244 gchar *contents;
1245 gsize size;
1247 g_return_val_if_fail (tables_sql_file != NULL, FALSE);
1249 priv = dbe->priv;
1251 g_return_val_if_fail (priv->db_connection != NULL, FALSE);
1253 /* read the contents of the file */
1254 if (g_file_get_contents (tables_sql_file, &contents, &size, &err) == FALSE)
1256 g_warning ("Something went wrong while trying to read %s",
1257 tables_sql_file);
1259 if (err != NULL)
1260 g_message ("%s", err->message);
1261 return FALSE;
1264 command = gda_command_new (contents, GDA_COMMAND_TYPE_SQL,
1265 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
1266 gda_connection_execute_non_select_command (priv->db_connection, command,
1267 NULL, NULL);
1268 gda_command_free (command);
1270 g_free (contents);
1274 * Check if the database already exists into the prj_directory
1276 gboolean
1277 symbol_db_engine_db_exists (SymbolDBEngine * dbe, gchar * prj_directory)
1279 SymbolDBEnginePriv *priv;
1281 g_return_val_if_fail (prj_directory != NULL, FALSE);
1283 priv = dbe->priv;
1285 /* check whether the db filename already exists.*/
1286 gchar *tmp_file = g_strdup_printf ("%s/%s.db", prj_directory,
1287 ANJUTA_DB_FILE);
1289 if (g_file_test (tmp_file, G_FILE_TEST_EXISTS) == FALSE)
1291 DEBUG_PRINT ("db %s does not exist", tmp_file);
1292 g_free (tmp_file);
1293 return FALSE;
1295 g_free (tmp_file);
1297 DEBUG_PRINT ("db %s does exist", tmp_file);
1298 return TRUE;
1302 * Open or create a new database at given directory.
1304 gboolean
1305 symbol_db_engine_open_db (SymbolDBEngine * dbe, gchar * prj_directory)
1307 SymbolDBEnginePriv *priv;
1308 /* Connection data */
1309 gchar *dsn_name;
1310 gboolean needs_tables_creation = FALSE;
1312 g_return_val_if_fail (prj_directory != NULL, FALSE);
1314 priv = dbe->priv;
1316 /* check whether the db filename already exists. If it's not the case
1317 * create the tables for the database. */
1318 gchar *tmp_file = g_strdup_printf ("%s/%s.db", prj_directory,
1319 ANJUTA_DB_FILE);
1321 if (g_file_test (tmp_file, G_FILE_TEST_EXISTS) == FALSE)
1323 needs_tables_creation = TRUE;
1325 g_free (tmp_file);
1328 priv->data_source = g_strdup (prj_directory);
1329 dsn_name = g_strdup_printf ("DB_DIR=%s;DB_NAME=%s", prj_directory,
1330 ANJUTA_DB_FILE);
1332 if (gda_config_save_data_source (priv->data_source, "SQLite",
1333 dsn_name, "Anjuta Project",
1334 "", "", FALSE) == FALSE)
1336 return FALSE;
1339 /* store the dsn name into Priv data. We can avoid to free it here coz it will
1340 * used later again. */
1341 priv->dsn_name = dsn_name;
1343 DEBUG_PRINT ("opening/connecting to database...");
1344 sdb_engine_connect_to_db (dbe, priv->data_source);
1346 if (needs_tables_creation == TRUE)
1348 DEBUG_PRINT ("creating tables: it needs tables...");
1349 sdb_engine_create_db_tables (dbe, TABLES_SQL);
1352 return TRUE;
1356 * @return -1 on error. Otherwise the id of table
1358 static gint
1359 sdb_engine_get_table_id_by_unique_name (SymbolDBEngine * dbe, query_type qtype,
1360 gchar * param_key,
1361 const GValue * param_value)
1363 const GdaQuery *query;
1364 GdaParameterList *par_list;
1365 GdaParameter *param;
1366 const GValue *num;
1367 gint table_id;
1369 /* get prepared query */
1370 if ((query = sdb_engine_get_query_by_id (dbe, qtype)) == NULL)
1372 g_warning ("query is null");
1373 return -1;
1376 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1377 == gda_query_get_query_type ((GdaQuery *) query))
1379 g_warning ("sdb_engine_get_table_id_by_unique_name: non parsed "
1380 "sql error");
1381 return -1;
1384 if ((par_list = gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
1386 g_warning ("par_list is NULL!\n");
1387 return -1;
1390 if ((param = gda_parameter_list_find_param (par_list, param_key)) == NULL)
1392 g_warning ("sdb_engine_get_table_id_by_unique_name: param is NULL "
1393 "from pquery!\n");
1394 return -1;
1397 gda_parameter_set_value (param, param_value);
1399 /* execute the query with parametes just set */
1400 GObject *obj =
1401 G_OBJECT (gda_query_execute ((GdaQuery *) query, par_list, FALSE,
1402 NULL));
1404 if (!GDA_IS_DATA_MODEL (obj) ||
1405 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj)) <= 0)
1407 /* DEBUG_PRINT ("could not retrieve table id by unique name [par %s]",
1408 param_key);*/
1410 if (obj != NULL)
1411 g_object_unref (obj);
1412 return -1;
1415 /* get and parse the results. */
1416 num = gda_data_model_get_value_at (GDA_DATA_MODEL (obj), 0, 0);
1418 table_id = g_value_get_int (num);
1419 g_object_unref (obj);
1420 return table_id;
1424 * This is the same as sdb_engine_get_table_id_by_unique_name () but for two
1425 * unique parameters. This should be the quickest way. Surely quicker than
1426 * use g_strdup_printf () with a va_list for example.
1427 * @return -1 on error. Otherwise the id of table
1430 static gint
1431 sdb_engine_get_table_id_by_unique_name2 (SymbolDBEngine * dbe, query_type qtype,
1432 gchar * param_key1,
1433 const GValue * value1,
1434 gchar * param_key2,
1435 const GValue * value2)
1437 const GdaQuery *query;
1438 GdaParameterList *par_list;
1439 GdaParameter *param;
1440 GValue *value;
1441 const GValue *num;
1442 gint table_id;
1444 /* get prepared query */
1445 if ((query = sdb_engine_get_query_by_id (dbe, qtype)) == NULL)
1447 g_warning ("query is null");
1448 return -1;
1451 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1452 == gda_query_get_query_type ((GdaQuery *) query))
1454 g_warning
1455 ("sdb_engine_get_table_id_by_unique_name2: non parsed sql error");
1456 return -1;
1459 if ((par_list = gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
1461 g_warning ("par_list is NULL!\n");
1462 return -1;
1465 /* look for and set the first parameter */
1466 if ((param = gda_parameter_list_find_param (par_list, param_key1)) == NULL)
1468 g_warning ("sdb_engine_get_table_id_by_unique_name2: "
1469 "param is NULL from pquery! [par1: %s] [par2: %s]\n",
1470 param_key1, param_key2);
1471 return -1;
1474 gda_parameter_set_value (param, value1);
1476 /* ...and the second one */
1477 if ((param = gda_parameter_list_find_param (par_list, param_key2)) == NULL)
1479 g_warning ("param is NULL from pquery!\n");
1480 return -1;
1483 gda_parameter_set_value (param, value2);
1485 /* execute the query with parametes just set */
1486 GObject *obj =
1487 G_OBJECT (gda_query_execute ((GdaQuery *) query, par_list, FALSE,
1488 NULL));
1490 if (!GDA_IS_DATA_MODEL (obj) ||
1491 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj)) <= 0)
1494 if (obj != NULL)
1495 g_object_unref (obj);
1496 return -1;
1499 /* get and parse the results. */
1500 num = gda_data_model_get_value_at (GDA_DATA_MODEL (obj), 0, 0);
1502 table_id = g_value_get_int (num);
1503 g_object_unref (obj);
1504 return table_id;
1507 static gint
1508 sdb_engine_get_table_id_by_unique_name3 (SymbolDBEngine * dbe, query_type qtype,
1509 gchar * param_key1,
1510 const GValue * value1,
1511 gchar * param_key2,
1512 const GValue * value2,
1513 gchar * param_key3,
1514 const GValue * value3)
1516 const GdaQuery *query;
1517 GdaParameterList *par_list;
1518 GdaParameter *param;
1519 GValue *value;
1520 const GValue *num;
1521 gint table_id;
1523 /* get prepared query */
1524 if ((query = sdb_engine_get_query_by_id (dbe, qtype)) == NULL)
1526 g_warning ("query is null");
1527 return -1;
1530 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1531 == gda_query_get_query_type ((GdaQuery *) query))
1533 g_warning
1534 ("sdb_engine_get_table_id_by_unique_name2: non parsed sql error");
1535 return -1;
1538 if ((par_list = gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
1540 g_warning ("par_list is NULL!\n");
1541 return -1;
1544 /* look for and set the first parameter */
1545 if ((param = gda_parameter_list_find_param (par_list, param_key1)) == NULL)
1547 g_warning ("sdb_engine_get_table_id_by_unique_name2: "
1548 "param is NULL from pquery! [par1: %s] [par2: %s]\n",
1549 param_key1, param_key2);
1550 return -1;
1553 gda_parameter_set_value (param, value1);
1555 /* ...and the second one */
1556 if ((param = gda_parameter_list_find_param (par_list, param_key2)) == NULL)
1558 g_warning ("param is NULL from pquery!\n");
1559 return -1;
1562 gda_parameter_set_value (param, value2);
1564 /* ...and the third one */
1565 if ((param = gda_parameter_list_find_param (par_list, param_key3)) == NULL)
1567 g_warning ("param is NULL from pquery!\n");
1568 return -1;
1571 gda_parameter_set_value (param, value3);
1574 /* execute the query with parametes just set */
1575 GObject *obj =
1576 G_OBJECT (gda_query_execute ((GdaQuery *) query, par_list, FALSE,
1577 NULL));
1579 if (!GDA_IS_DATA_MODEL (obj) ||
1580 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj)) <= 0)
1583 if (obj != NULL)
1584 g_object_unref (obj);
1585 return -1;
1588 /* get and parse the results. */
1589 num = gda_data_model_get_value_at (GDA_DATA_MODEL (obj), 0, 0);
1591 table_id = g_value_get_int (num);
1592 g_object_unref (obj);
1593 return table_id;
1597 gboolean
1598 symbol_db_engine_add_new_workspace (SymbolDBEngine * dbe,
1599 gchar * workspace_name)
1602 CREATE TABLE workspace (workspace_id integer PRIMARY KEY AUTOINCREMENT,
1603 workspace_name varchar (50) not null unique,
1604 analize_time DATE
1607 const GdaQuery *query;
1608 GdaParameterList *par_list;
1609 GdaParameter *param;
1610 GValue *value;
1611 SymbolDBEnginePriv *priv;
1613 priv = dbe->priv;
1615 g_return_val_if_fail (priv->db_connection != NULL, FALSE);
1618 if ((query =
1619 sdb_engine_get_query_by_id (dbe, PREP_QUERY_WORKSPACE_NEW)) == NULL)
1621 g_warning ("query is null");
1622 return FALSE;
1625 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
1626 gda_query_get_query_type ((GdaQuery *) query))
1628 g_warning ("non parsed sql error");
1629 return FALSE;
1632 if ((par_list = gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
1634 g_warning ("par_list is NULL!\n");
1635 return FALSE;
1638 if ((param = gda_parameter_list_find_param (par_list, "wsname")) == NULL)
1640 g_warning ("param is NULL from pquery!\n");
1641 return FALSE;
1644 value = gda_value_new (G_TYPE_STRING);
1645 g_value_set_string (value, workspace_name);
1647 gda_parameter_set_value (param, value);
1649 /* execute the query with parametes just set */
1650 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
1651 gda_value_free (value);
1652 return TRUE;
1656 * Return the name of the opened project.
1657 * NULL on error. Returned string must be freed by caller.
1659 gchar*
1660 symbol_db_engine_get_opened_project_name (SymbolDBEngine * dbe)
1662 SymbolDBEnginePriv *priv;
1663 gint prj_id;
1665 g_return_val_if_fail (dbe != NULL, NULL);
1666 priv = dbe->priv;
1668 g_return_val_if_fail (priv->db_connection != NULL, NULL);
1670 return g_strdup (priv->project_name);
1674 * Open a new project.
1675 * It will test if project was correctly created.
1677 gboolean
1678 symbol_db_engine_open_project (SymbolDBEngine * dbe, /*gchar* workspace, */
1679 const gchar * project_name)
1681 const GdaQuery *query;
1682 GdaParameterList *par_list;
1683 GdaParameter *param;
1684 GValue *value;
1685 SymbolDBEnginePriv *priv;
1686 gint prj_id;
1688 priv = dbe->priv;
1690 g_return_val_if_fail (priv->db_connection != NULL, FALSE);
1691 if (symbol_db_engine_is_project_opened (dbe, project_name) == TRUE) {
1692 g_warning ("project already opened, %s (priv %s)", project_name,
1693 priv->project_name);
1694 return FALSE;
1697 value = gda_value_new (G_TYPE_STRING);
1698 g_value_set_string (value, project_name);
1700 /* test the existence of the project in db */
1701 if ((prj_id = sdb_engine_get_table_id_by_unique_name (dbe,
1702 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME,
1703 "prjname",
1704 value)) <= 0)
1706 gda_value_free (value);
1707 return FALSE;
1710 gda_value_free (value);
1712 /* open the project... */
1713 priv->project_name = g_strdup (project_name);
1715 return TRUE;
1719 gboolean
1720 symbol_db_engine_close_project (SymbolDBEngine *dbe, gchar* project_name)
1722 SymbolDBEnginePriv *priv;
1724 priv = dbe->priv;
1726 if (priv->project_name)
1728 g_free (priv->project_name);
1729 priv->project_name = NULL;
1732 sdb_engine_disconnect_from_db (dbe);
1737 * @param workspace Can be NULL. In that case a default workspace will be created,
1738 * and project will depend on that.
1739 * @param project Project name. Must NOT be NULL.
1741 // FIXME: file_include file_ignore
1742 gboolean
1743 symbol_db_engine_add_new_project (SymbolDBEngine * dbe, gchar * workspace,
1744 gchar * project)
1747 CREATE TABLE project (project_id integer PRIMARY KEY AUTOINCREMENT,
1748 project_name varchar (50) not null unique,
1749 wrkspace_id integer REFERENCES workspace (workspace_id),
1750 analize_time DATE
1753 const GdaQuery *query;
1754 GdaParameterList *par_list;
1755 GdaParameter *param;
1756 GValue *value;
1757 gchar *workspace_name;
1758 gint wks_id;
1759 SymbolDBEnginePriv *priv;
1761 g_return_val_if_fail (dbe != NULL, FALSE);
1763 priv = dbe->priv;
1765 if (symbol_db_engine_is_project_opened (dbe, project) == TRUE)
1767 g_warning ("You have an already opened project. Cannot continue.");
1768 return FALSE;
1771 if (workspace == NULL)
1773 workspace_name = "anjuta_workspace_default";
1775 DEBUG_PRINT ("adding default workspace...");
1776 if (symbol_db_engine_add_new_workspace (dbe, workspace_name) == FALSE)
1778 DEBUG_PRINT ("Project cannot be added because a default workspace "
1779 "cannot be created");
1780 return FALSE;
1783 else
1785 workspace_name = workspace;
1788 value = gda_value_new (G_TYPE_STRING);
1789 g_value_set_string (value, workspace_name);
1791 /* get workspace id */
1792 if ((wks_id = sdb_engine_get_table_id_by_unique_name (dbe,
1793 PREP_QUERY_GET_WORKSPACE_ID_BY_UNIQUE_NAME,
1794 "wsname",
1795 value)) <= 0)
1797 DEBUG_PRINT ("no workspace id");
1798 gda_value_free (value);
1799 return FALSE;
1802 /* insert new project */
1803 if ((query =
1804 sdb_engine_get_query_by_id (dbe, PREP_QUERY_PROJECT_NEW)) == NULL)
1806 g_warning ("query is null");
1807 gda_value_free (value);
1808 return FALSE;
1811 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
1812 gda_query_get_query_type ((GdaQuery *) query))
1814 g_warning ("non parsed sql error");
1815 gda_value_free (value);
1816 return FALSE;
1819 if ((par_list = gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
1821 g_warning ("par_list is NULL!\n");
1822 gda_value_free (value);
1823 return FALSE;
1826 if ((param = gda_parameter_list_find_param (par_list, "prjname")) == NULL)
1828 g_warning ("param prjname is NULL from pquery!");
1829 gda_value_free (value);
1830 return FALSE;
1833 gda_value_reset_with_type (value, G_TYPE_STRING);
1834 g_value_set_string (value, project);
1835 gda_parameter_set_value (param, value);
1837 if ((param = gda_parameter_list_find_param (par_list, "wsid")) == NULL)
1839 g_warning ("param is NULL from pquery!");
1840 return FALSE;
1843 gda_value_reset_with_type (value, G_TYPE_INT);
1844 g_value_set_int (value, wks_id);
1846 gda_parameter_set_value (param, value);
1848 /* execute the query with parametes just set */
1849 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
1850 gda_value_free (value);
1852 return TRUE;
1856 static gint
1857 sdb_engine_add_new_language (SymbolDBEngine * dbe, gchar * language)
1860 CREATE TABLE language (language_id integer PRIMARY KEY AUTOINCREMENT,
1861 language_name varchar (50) not null unique);
1863 gint table_id;
1864 GValue *value;
1866 g_return_val_if_fail (language != NULL, -1);
1868 value = gda_value_new (G_TYPE_STRING);
1869 g_value_set_string (value, language);
1871 /* check for an already existing table with language "name". */
1872 if ((table_id = sdb_engine_get_table_id_by_unique_name (dbe,
1873 PREP_QUERY_GET_LANGUAGE_ID_BY_UNIQUE_NAME,
1874 "langname",
1875 value)) < 0)
1878 /* insert a new entry on db */
1879 const GdaQuery *query;
1880 GdaParameterList *par_list;
1881 GdaParameter *param;
1882 GValue *value;
1884 if ((query = sdb_engine_get_query_by_id (dbe, PREP_QUERY_LANGUAGE_NEW))
1885 == NULL)
1887 g_warning ("query is null");
1888 return FALSE;
1891 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
1892 gda_query_get_query_type ((GdaQuery *) query))
1894 g_warning ("non parsed sql error");
1895 return FALSE;
1898 if ((par_list =
1899 gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
1901 g_warning ("par_list is NULL!\n");
1902 return FALSE;
1905 if ((param =
1906 gda_parameter_list_find_param (par_list, "langname")) == NULL)
1908 g_warning ("param langname is NULL from pquery!");
1909 return FALSE;
1912 value = gda_value_new (G_TYPE_STRING);
1913 g_value_set_string (value, language);
1915 gda_parameter_set_value (param, value);
1916 gda_value_free (value);
1917 /* execute the query with parametes just set */
1918 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
1920 table_id = sdb_engine_get_last_insert_id (dbe);
1922 gda_value_free (value);
1923 return table_id;
1927 /* Add a file to project.
1928 * This function requires an opened db, i.e. calling before
1929 * symbol_db_engine_open_db ()
1930 * filepath: referes to a full file path.
1931 * WARNING: we suppose that project is already opened.
1933 static gboolean
1934 sdb_engine_add_new_file (SymbolDBEngine * dbe, gchar * project,
1935 const gchar * filepath, gchar * language)
1938 CREATE TABLE file (file_id integer PRIMARY KEY AUTOINCREMENT,
1939 file_path TEXT not null unique,
1940 prj_id integer REFERENCES project (projec_id),
1941 lang_id integer REFERENCES language (language_id),
1942 analize_time DATE
1945 SymbolDBEnginePriv *priv;
1946 gint project_id;
1947 gint language_id;
1948 gint file_id;
1949 GValue *value;
1951 priv = dbe->priv;
1953 value = gda_value_new (G_TYPE_STRING);
1954 g_value_set_string (value, project);
1956 /* check for an already existing table with project "project". */
1957 if ((project_id = sdb_engine_get_table_id_by_unique_name (dbe,
1958 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME,
1959 "prjname",
1960 value)) < 0)
1962 g_warning ("no project with that name exists");
1963 gda_value_free (value);
1964 return FALSE;
1967 gda_value_free (value);
1968 value = gda_value_new (G_TYPE_STRING);
1969 /* we're gonna set the file relative to the project folder, not the full one.
1970 * e.g.: we have a file on disk: "/tmp/foo/src/file.c" and a datasource located on
1971 * "/tmp/foo". The entry on db will be "src/file.c"
1973 g_value_set_string (value, filepath + strlen(priv->data_source));
1975 if ((file_id = sdb_engine_get_table_id_by_unique_name (dbe,
1976 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME,
1977 "filepath",
1978 value)) < 0)
1980 /* insert a new entry on db */
1981 const GdaQuery *query;
1982 GdaParameterList *par_list;
1983 GdaParameter *param;
1984 GValue *value;
1986 language_id = sdb_engine_add_new_language (dbe, language);
1988 if ((query = sdb_engine_get_query_by_id (dbe, PREP_QUERY_FILE_NEW))
1989 == NULL)
1991 g_warning ("query is null");
1992 return FALSE;
1995 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
1996 gda_query_get_query_type ((GdaQuery *) query))
1998 g_warning ("non parsed sql error");
1999 return FALSE;
2002 if ((par_list =
2003 gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
2005 g_warning ("par_list is NULL!\n");
2006 return FALSE;
2009 /* filepath parameter */
2010 if ((param =
2011 gda_parameter_list_find_param (par_list, "filepath")) == NULL)
2013 g_warning ("param filepath is NULL from pquery!");
2014 return FALSE;
2017 value = gda_value_new (G_TYPE_STRING);
2018 /* relative filepath */
2019 g_value_set_string (value, filepath + strlen(priv->data_source));
2020 gda_parameter_set_value (param, value);
2022 /* project id parameter */
2023 if ((param = gda_parameter_list_find_param (par_list, "prjid")) == NULL)
2025 g_warning ("param prjid is NULL from pquery!");
2026 return FALSE;
2029 gda_value_reset_with_type (value, G_TYPE_INT);
2030 g_value_set_int (value, project_id);
2031 gda_parameter_set_value (param, value);
2033 /* language id parameter */
2034 if ((param =
2035 gda_parameter_list_find_param (par_list, "langid")) == NULL)
2037 g_warning ("param langid is NULL from pquery!");
2038 return FALSE;
2041 gda_value_reset_with_type (value, G_TYPE_INT);
2042 g_value_set_int (value, language_id);
2043 gda_parameter_set_value (param, value);
2044 gda_value_free (value);
2046 /* execute the query with parametes just set */
2047 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
2049 gda_value_free (value);
2051 return TRUE;
2054 gboolean
2055 symbol_db_engine_add_new_files (SymbolDBEngine * dbe, gchar * project,
2056 const GPtrArray * files_path, gchar * language,
2057 gboolean scan_symbols)
2059 gint i;
2060 SymbolDBEnginePriv *priv;
2062 g_return_val_if_fail (dbe != NULL, FALSE);
2063 priv = dbe->priv;
2065 g_return_val_if_fail (priv->db_connection != NULL, FALSE);
2066 g_return_val_if_fail (project != NULL, FALSE);
2068 if (symbol_db_engine_is_project_opened (dbe, project) == FALSE)
2070 g_warning ("your project isn't opened, %s (priv %s)", project,
2071 priv->project_name);
2072 return FALSE;
2075 for (i = 0; i < files_path->len; i++)
2077 gchar *node = (gchar *) g_ptr_array_index (files_path, i);
2079 /* test the existance of node file */
2080 if (g_file_test (node, G_FILE_TEST_EXISTS) == FALSE)
2082 g_warning ("File %s doesn't exist", node);
2083 continue;
2086 DEBUG_PRINT ("gonna adding symbols for %s", node);
2088 if (sdb_engine_add_new_file (dbe, project, node, language) == FALSE)
2090 g_warning ("Error processing file %s", node);
2091 return FALSE;
2096 /* perform the scan of files. It will spawn a fork() process with
2097 * AnjutaLauncher and ctags in server mode. After the ctags cmd has been
2098 * executed, the populating process'll take place.
2100 if (scan_symbols)
2101 return sdb_engine_scan_files_1 (dbe, files_path, NULL, FALSE);
2103 return TRUE;
2107 static gint
2108 sdb_engine_add_new_sym_type (SymbolDBEngine * dbe, tagEntry * tag_entry)
2111 CREATE TABLE sym_type (type_id integer PRIMARY KEY AUTOINCREMENT,
2112 type varchar (256) not null ,
2113 type_name varchar (256) not null ,
2114 unique (type, type_name)
2117 const gchar *type;
2118 const gchar *type_name;
2119 gint table_id;
2120 GValue *value1, *value2;
2122 g_return_val_if_fail (tag_entry != NULL, -1);
2124 type = tag_entry->kind;
2125 type_name = tag_entry->name;
2127 value1 = gda_value_new (G_TYPE_STRING);
2128 g_value_set_string (value1, type);
2130 value2 = gda_value_new (G_TYPE_STRING);
2131 g_value_set_string (value2, type_name);
2133 if ((table_id = sdb_engine_get_table_id_by_unique_name2 (dbe,
2134 PREP_QUERY_GET_SYM_TYPE_ID,
2135 "type", value1,
2136 "typename",
2137 value2)) < 0)
2139 const GdaQuery *query;
2140 GdaParameterList *par_list;
2141 GdaParameter *param;
2142 GValue *value;
2144 /* it does not exist. Create a new tuple. */
2145 if ((query = sdb_engine_get_query_by_id (dbe, PREP_QUERY_SYM_TYPE_NEW))
2146 == NULL)
2148 g_warning ("query is null");
2149 return -1;
2152 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
2153 gda_query_get_query_type ((GdaQuery *) query))
2155 g_warning ("non parsed sql error");
2156 return -1;
2159 if ((par_list =
2160 gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
2162 g_warning ("par_list is NULL!\n");
2163 return -1;
2166 /* type parameter */
2167 if ((param = gda_parameter_list_find_param (par_list, "type")) == NULL)
2169 g_warning ("param type is NULL from pquery!");
2170 return -1;
2173 value = gda_value_new (G_TYPE_STRING);
2174 g_value_set_string (value, type);
2175 gda_parameter_set_value (param, value);
2177 /* type_name parameter */
2178 if ((param =
2179 gda_parameter_list_find_param (par_list, "typename")) == NULL)
2181 g_warning ("param typename is NULL from pquery!");
2182 return -1;
2185 gda_value_reset_with_type (value, G_TYPE_STRING);
2186 g_value_set_string (value, type_name);
2187 gda_parameter_set_value (param, value);
2188 gda_value_free (value);
2190 /* execute the query with parametes just set */
2191 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
2193 table_id = sdb_engine_get_last_insert_id (dbe);
2196 gda_value_free (value1);
2197 gda_value_free (value2);
2199 return table_id;
2202 static gint
2203 sdb_engine_add_new_sym_kind (SymbolDBEngine * dbe, tagEntry * tag_entry)
2206 CREATE TABLE sym_kind (sym_kind_id integer PRIMARY KEY AUTOINCREMENT,
2207 kind_name varchar (50) not null unique
2210 const gchar *kind_name;
2211 gint table_id;
2212 GValue *value;
2214 g_return_val_if_fail (tag_entry != NULL, -1);
2216 kind_name = tag_entry->kind;
2218 /* no kind associated with current tag */
2219 if (kind_name == NULL)
2220 return -1;
2222 value = gda_value_new (G_TYPE_STRING);
2223 g_value_set_string (value, kind_name);
2225 if ((table_id = sdb_engine_get_table_id_by_unique_name (dbe,
2226 PREP_QUERY_GET_SYM_KIND_BY_UNIQUE_NAME,
2227 "kindname",
2228 value)) < 0)
2230 const GdaQuery *query;
2231 GdaParameterList *par_list;
2232 GdaParameter *param;
2233 GValue *value;
2235 /* not found. Go on with inserting */
2236 gchar *query_str;
2238 if ((query = sdb_engine_get_query_by_id (dbe, PREP_QUERY_SYM_KIND_NEW))
2239 == NULL)
2241 g_warning ("query is null");
2242 return -1;
2245 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
2246 gda_query_get_query_type ((GdaQuery *) query))
2248 g_warning ("non parsed sql error");
2249 return -1;
2252 if ((par_list =
2253 gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
2255 g_warning ("par_list is NULL!\n");
2256 return -1;
2259 /* kindname parameter */
2260 if ((param =
2261 gda_parameter_list_find_param (par_list, "kindname")) == NULL)
2263 g_warning ("param kindname is NULL from pquery!");
2264 return -1;
2267 value = gda_value_new (G_TYPE_STRING);
2268 g_value_set_string (value, kind_name);
2269 gda_parameter_set_value (param, value);
2270 gda_value_free (value);
2272 /* execute the query with parametes just set */
2273 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
2275 table_id = sdb_engine_get_last_insert_id (dbe);
2277 gda_value_free (value);
2278 return table_id;
2281 static gint
2282 sdb_engine_add_new_sym_access (SymbolDBEngine * dbe, tagEntry * tag_entry)
2285 CREATE TABLE sym_access (access_kind_id integer PRIMARY KEY AUTOINCREMENT,
2286 access_name varchar (50) not null unique
2289 const gchar *access;
2290 gint table_id;
2291 GValue *value;
2293 g_return_val_if_fail (tag_entry != NULL, -1);
2295 if ((access = tagsField (tag_entry, "access")) == NULL)
2297 /* no access associated with current tag */
2298 return -1;
2301 value = gda_value_new (G_TYPE_STRING);
2302 g_value_set_string (value, access);
2304 if ((table_id = sdb_engine_get_table_id_by_unique_name (dbe,
2305 PREP_QUERY_GET_SYM_ACCESS_BY_UNIQUE_NAME,
2306 "accesskind",
2307 value)) < 0)
2309 const GdaQuery *query;
2310 GdaParameterList *par_list;
2311 GdaParameter *param;
2312 GValue *value;
2314 /* not found. Go on with inserting */
2315 gchar *query_str;
2317 if ((query =
2318 sdb_engine_get_query_by_id (dbe,
2319 PREP_QUERY_SYM_ACCESS_NEW)) == NULL)
2321 g_warning ("query is null");
2322 return -1;
2325 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
2326 gda_query_get_query_type ((GdaQuery *) query))
2328 g_warning ("non parsed sql error");
2329 return -1;
2332 if ((par_list =
2333 gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
2335 g_warning ("par_list is NULL!\n");
2336 return -1;
2339 /* accesskind parameter */
2340 if ((param =
2341 gda_parameter_list_find_param (par_list, "accesskind")) == NULL)
2343 g_warning ("param accesskind is NULL from pquery!");
2344 return -1;
2347 value = gda_value_new (G_TYPE_STRING);
2348 g_value_set_string (value, access);
2349 gda_parameter_set_value (param, value);
2350 gda_value_free (value);
2352 /* execute the query with parametes just set */
2353 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
2355 table_id = sdb_engine_get_last_insert_id (dbe);
2357 gda_value_free (value);
2358 return table_id;
2361 static gint
2362 sdb_engine_add_new_sym_implementation (SymbolDBEngine * dbe,
2363 tagEntry * tag_entry)
2366 CREATE TABLE sym_implementation (sym_impl_id integer PRIMARY KEY AUTOINCREMENT,
2367 implementation_name varchar (50) not null unique
2370 const gchar *implementation;
2371 gint table_id;
2372 GValue *value;
2374 g_return_val_if_fail (tag_entry != NULL, -1);
2376 if ((implementation = tagsField (tag_entry, "implementation")) == NULL)
2378 /* no implementation associated with current tag */
2379 return -1;
2382 value = gda_value_new (G_TYPE_STRING);
2383 g_value_set_string (value, implementation);
2385 if ((table_id = sdb_engine_get_table_id_by_unique_name (dbe,
2386 PREP_QUERY_GET_SYM_IMPLEMENTATION_BY_UNIQUE_NAME,
2387 "implekind",
2388 value)) < 0)
2390 const GdaQuery *query;
2391 GdaParameterList *par_list;
2392 GdaParameter *param;
2393 GValue *value;
2395 /* not found. Go on with inserting */
2396 if ((query =
2397 sdb_engine_get_query_by_id (dbe,
2398 PREP_QUERY_SYM_IMPLEMENTATION_NEW)) ==
2399 NULL)
2401 g_warning ("query is null");
2402 return -1;
2405 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
2406 gda_query_get_query_type ((GdaQuery *) query))
2408 g_warning ("non parsed sql error");
2409 return -1;
2412 if ((par_list =
2413 gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
2415 g_warning ("par_list is NULL!\n");
2416 return -1;
2419 /* implekind parameter */
2420 if ((param =
2421 gda_parameter_list_find_param (par_list, "implekind")) == NULL)
2423 g_warning ("param implekind is NULL from pquery!");
2424 return -1;
2427 value = gda_value_new (G_TYPE_STRING);
2428 g_value_set_string (value, implementation);
2429 gda_parameter_set_value (param, value);
2430 gda_value_free (value);
2432 /* execute the query with parametes just set */
2433 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
2435 table_id = sdb_engine_get_last_insert_id (dbe);
2437 gda_value_free (value);
2438 return table_id;
2442 static void
2443 sdb_engine_add_new_heritage (SymbolDBEngine * dbe, gint base_symbol_id,
2444 gint derived_symbol_id)
2447 CREATE TABLE heritage (symbol_id_base integer REFERENCES symbol (symbol_id),
2448 symbol_id_derived integer REFERENCES symbol (symbol_id),
2449 PRIMARY KEY (symbol_id_base, symbol_id_derived)
2452 const GdaQuery *query;
2453 GdaParameterList *par_list;
2454 GdaParameter *param;
2455 GValue *value;
2457 g_return_if_fail (base_symbol_id > 0);
2458 g_return_if_fail (derived_symbol_id > 0);
2460 if ((query = sdb_engine_get_query_by_id (dbe, PREP_QUERY_HERITAGE_NEW))
2461 == NULL)
2463 g_warning ("query is null");
2464 return;
2467 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
2468 gda_query_get_query_type ((GdaQuery *) query))
2470 g_warning ("non parsed sql error");
2471 return;
2474 if ((par_list = gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
2476 g_warning ("par_list is NULL!\n");
2477 return;
2480 /* symbase parameter */
2481 if ((param = gda_parameter_list_find_param (par_list, "symbase")) == NULL)
2483 g_warning ("param symbase is NULL from pquery!");
2484 return;
2487 value = gda_value_new (G_TYPE_INT);
2488 g_value_set_int (value, base_symbol_id);
2489 gda_parameter_set_value (param, value);
2491 /* symderived id parameter */
2492 if ((param =
2493 gda_parameter_list_find_param (par_list, "symderived")) == NULL)
2495 g_warning ("param symderived is NULL from pquery!");
2496 return;
2499 gda_value_reset_with_type (value, G_TYPE_INT);
2500 g_value_set_int (value, derived_symbol_id);
2501 gda_parameter_set_value (param, value);
2502 gda_value_free (value);
2504 /* execute the query with parametes just set */
2505 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
2509 static gint
2510 sdb_engine_add_new_scope_definition (SymbolDBEngine * dbe, tagEntry * tag_entry)
2513 CREATE TABLE scope (scope_id integer PRIMARY KEY AUTOINCREMENT,
2514 scope varchar(256) not null,
2515 type_id integer REFERENCES sym_type (type_id),
2516 unique (scope, type_id)
2519 const gchar *scope;
2520 GValue *value1, *value2;
2521 gint type_table_id, table_id;
2523 g_return_val_if_fail (tag_entry != NULL, -1);
2524 g_return_val_if_fail (tag_entry->kind != NULL, -1);
2526 /* This symbol will define a scope which name is tag_entry->name
2527 * For example if we get a tag MyFoo with kind "namespace", it will define
2528 * the "MyFoo" scope, which type is "namespace MyFoo"
2530 scope = tag_entry->name;
2532 /* filter out 'variable' and 'member' kinds. They define no scope. */
2533 if (strcmp (tag_entry->kind, "variable") == 0 ||
2534 strcmp (tag_entry->kind, "member") == 0)
2536 return -1;
2539 value1 = gda_value_new (G_TYPE_STRING);
2540 g_value_set_string (value1, tag_entry->kind);
2542 value2 = gda_value_new (G_TYPE_STRING);
2543 g_value_set_string (value2, scope);
2545 /* search for type_id on sym_type table */
2546 if ((type_table_id = sdb_engine_get_table_id_by_unique_name2 (dbe,
2547 PREP_QUERY_GET_SYM_TYPE_ID,
2548 "type",
2549 value1,
2550 "typename",
2551 value2)) < 0)
2553 /* no type has been found. */
2554 gda_value_free (value1);
2555 gda_value_free (value2);
2557 return -1;
2560 /* let's check for an already present scope table with scope and type_id infos. */
2561 gda_value_reset_with_type (value1, G_TYPE_STRING);
2562 g_value_set_string (value1, scope);
2564 gda_value_reset_with_type (value2, G_TYPE_INT);
2565 g_value_set_int (value2, type_table_id);
2567 if ((table_id = sdb_engine_get_table_id_by_unique_name2 (dbe,
2568 PREP_QUERY_GET_SCOPE_ID,
2569 "scope", value1,
2570 "typeid",
2571 value2)) < 0)
2573 /* no luck. A table with the pair scope and type_id is not present.
2574 * ok, let's insert out new scope table.
2576 const GdaQuery *query;
2577 GdaParameterList *par_list;
2578 GdaParameter *param;
2579 GValue *value;
2581 if ((query = sdb_engine_get_query_by_id (dbe, PREP_QUERY_SCOPE_NEW))
2582 == NULL)
2584 g_warning ("query is null");
2585 return;
2588 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
2589 gda_query_get_query_type ((GdaQuery *) query))
2591 g_warning ("non parsed sql error");
2592 return;
2595 if ((par_list =
2596 gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
2598 g_warning ("par_list is NULL!\n");
2599 return;
2602 /* scope parameter */
2603 if ((param = gda_parameter_list_find_param (par_list, "scope")) == NULL)
2605 g_warning ("param scope is NULL from pquery!");
2606 return;
2609 value = gda_value_new (G_TYPE_STRING);
2610 g_value_set_string (value, scope);
2611 gda_parameter_set_value (param, value);
2613 /* typeid parameter */
2614 if ((param =
2615 gda_parameter_list_find_param (par_list, "typeid")) == NULL)
2617 g_warning ("param typeid is NULL from pquery!");
2618 return;
2621 gda_value_reset_with_type (value, G_TYPE_INT);
2622 g_value_set_int (value, type_table_id);
2623 gda_parameter_set_value (param, value);
2624 gda_value_free (value);
2626 /* execute the query with parametes just set */
2627 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
2629 table_id = sdb_engine_get_last_insert_id (dbe);
2632 gda_value_free (value1);
2633 gda_value_free (value2);
2634 return table_id;
2638 * Saves the tagEntry info for a second pass parsing.
2639 * Usually we don't know all the symbol at the first scan of the tags. We need
2640 * a second one. These tuples are created for that purpose.
2642 * @return the table_id of the inserted tuple. -1 on error.
2644 static gint
2645 sdb_engine_add_new_tmp_heritage_scope (SymbolDBEngine * dbe,
2646 tagEntry * tag_entry,
2647 gint symbol_referer_id)
2650 CREATE TABLE __tmp_heritage_scope (tmp_heritage_scope_id integer PRIMARY KEY
2651 AUTOINCREMENT,
2652 symbol_referer_id integer not null,
2653 field_inherits varchar(256) not null,
2654 field_struct varchar(256),
2655 field_typeref varchar(256),
2656 field_enum varchar(256),
2657 field_union varchar(256),
2658 field_class varchar(256),
2659 field_namespace varchar(256)
2662 const GdaQuery *query;
2663 GdaParameterList *par_list;
2664 GdaParameter *param;
2665 gint table_id;
2666 GValue *value;
2667 const gchar *field_inherits, *field_struct, *field_typeref,
2668 *field_enum, *field_union, *field_class, *field_namespace;
2669 gboolean good_tag;
2671 g_return_val_if_fail (tag_entry != NULL, -1);
2673 /* init the flag */
2674 good_tag = FALSE;
2676 if ((field_inherits = tagsField (tag_entry, "inherits")) == NULL)
2678 field_inherits = "";
2680 else
2681 good_tag = TRUE;
2683 if ((field_struct = tagsField (tag_entry, "struct")) == NULL)
2685 field_struct = "";
2687 else
2688 good_tag = TRUE;
2690 if ((field_typeref = tagsField (tag_entry, "typeref")) == NULL)
2692 field_typeref = "";
2694 else
2695 good_tag = TRUE;
2697 if ((field_enum = tagsField (tag_entry, "enum")) == NULL)
2699 field_enum = "";
2701 else
2702 good_tag = TRUE;
2704 if ((field_union = tagsField (tag_entry, "union")) == NULL)
2706 field_union = "";
2708 else
2709 good_tag = TRUE;
2711 if ((field_class = tagsField (tag_entry, "class")) == NULL)
2713 field_class = "";
2715 else
2716 good_tag = TRUE;
2718 if ((field_namespace = tagsField (tag_entry, "namespace")) == NULL)
2720 field_namespace = "";
2722 else
2723 good_tag = TRUE;
2725 if (!good_tag)
2726 return -1;
2729 if ((query = sdb_engine_get_query_by_id (dbe, PREP_QUERY_TMP_HERITAGE_NEW))
2730 == NULL)
2732 g_warning ("query is null");
2733 return -1;
2736 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
2737 gda_query_get_query_type ((GdaQuery *) query))
2739 g_warning ("non parsed sql error");
2740 return;
2743 if ((par_list = gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
2745 g_warning ("par_list is NULL!\n");
2746 return;
2749 /* symreferid parameter */
2750 if ((param =
2751 gda_parameter_list_find_param (par_list, "symreferid")) == NULL)
2753 g_warning ("param symreferid is NULL from pquery!");
2754 return;
2757 value = gda_value_new (G_TYPE_INT);
2758 g_value_set_int (value, symbol_referer_id);
2759 gda_parameter_set_value (param, value);
2761 /* finherits parameter */
2762 if ((param = gda_parameter_list_find_param (par_list, "finherits")) == NULL)
2764 g_warning ("param finherits is NULL from pquery!");
2765 return;
2768 gda_value_reset_with_type (value, G_TYPE_STRING);
2769 g_value_set_string (value, field_inherits);
2770 gda_parameter_set_value (param, value);
2772 /* fstruct parameter */
2773 if ((param = gda_parameter_list_find_param (par_list, "fstruct")) == NULL)
2775 g_warning ("param fstruct is NULL from pquery!");
2776 return;
2779 gda_value_reset_with_type (value, G_TYPE_STRING);
2780 g_value_set_string (value, field_struct);
2781 gda_parameter_set_value (param, value);
2783 /* ftyperef parameter */
2784 if ((param = gda_parameter_list_find_param (par_list, "ftyperef")) == NULL)
2786 g_warning ("param ftyperef is NULL from pquery!");
2787 return;
2790 gda_value_reset_with_type (value, G_TYPE_STRING);
2791 g_value_set_string (value, field_typeref);
2792 gda_parameter_set_value (param, value);
2794 /* fenum parameter */
2795 if ((param = gda_parameter_list_find_param (par_list, "fenum")) == NULL)
2797 g_warning ("param fenum is NULL from pquery!");
2798 return;
2801 gda_value_reset_with_type (value, G_TYPE_STRING);
2802 g_value_set_string (value, field_enum);
2803 gda_parameter_set_value (param, value);
2805 /* funion parameter */
2806 if ((param = gda_parameter_list_find_param (par_list, "funion")) == NULL)
2808 g_warning ("param funion is NULL from pquery!");
2809 return;
2812 gda_value_reset_with_type (value, G_TYPE_STRING);
2813 g_value_set_string (value, field_union);
2814 gda_parameter_set_value (param, value);
2816 /* fclass parameter */
2817 if ((param = gda_parameter_list_find_param (par_list, "fclass")) == NULL)
2819 g_warning ("param fclass is NULL from pquery!");
2820 return;
2823 gda_value_reset_with_type (value, G_TYPE_STRING);
2824 g_value_set_string (value, field_class);
2825 gda_parameter_set_value (param, value);
2827 /* fnamespace parameter */
2828 if ((param =
2829 gda_parameter_list_find_param (par_list, "fnamespace")) == NULL)
2831 g_warning ("param fnamespace is NULL from pquery!");
2832 return;
2835 gda_value_reset_with_type (value, G_TYPE_STRING);
2836 g_value_set_string (value, field_namespace);
2837 gda_parameter_set_value (param, value);
2838 gda_value_free (value);
2841 /* execute the query with parametes just set */
2842 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
2844 table_id = sdb_engine_get_last_insert_id (dbe);
2845 return table_id;
2848 static gboolean
2849 sdb_engine_second_pass_update_scope_1 (SymbolDBEngine * dbe,
2850 GdaDataModel * data, gint data_row,
2851 gchar * token_name,
2852 const GValue * token_value)
2854 gint scope_id;
2855 GdaCommand *command;
2856 GValue *value1, *value2, *value;
2857 const GValue *value_id2;
2858 gint symbol_id;
2859 const gchar *tmp_str;
2860 gchar **tmp_str_splitted;
2861 gint tmp_str_splitted_length;
2862 gchar *object_name = NULL;
2863 gboolean free_token_name = FALSE;
2864 const GdaQuery *query;
2865 GdaParameterList *par_list;
2866 GdaParameter *param;
2868 tmp_str = g_value_get_string (token_value);
2870 /* we don't need empty strings */
2871 if (strcmp (tmp_str, "") == 0)
2872 return FALSE;
2874 /* we could have something like "First::Second::Third::Fourth" as tmp_str, so
2875 * take only the lastscope, in this case 'Fourth'.
2877 tmp_str_splitted = g_strsplit (tmp_str, ":", 0);
2878 tmp_str_splitted_length = g_strv_length (tmp_str_splitted);
2880 if (tmp_str_splitted_length > 0)
2882 /* handle special typedef case. Usually we have something like struct:my_foo.
2883 * splitting we have [0]-> struct [1]-> my_foo
2885 if (strcmp (token_name, "typedef") == 0)
2887 free_token_name = TRUE;
2888 token_name = g_strdup (tmp_str_splitted[0]);
2891 object_name = g_strdup (tmp_str_splitted[tmp_str_splitted_length - 1]);
2893 else
2895 g_strfreev (tmp_str_splitted);
2896 return FALSE;
2899 g_strfreev (tmp_str_splitted);
2902 * DEBUG_PRINT ("2nd pass scope: got %s %s (from %s)", token_name, object_name,
2903 * tmp_str); */
2905 value1 = gda_value_new (G_TYPE_STRING);
2906 g_value_set_string (value1, token_name);
2908 value2 = gda_value_new (G_TYPE_STRING);
2909 g_value_set_string (value2, object_name);
2911 if ((scope_id = sdb_engine_get_table_id_by_unique_name2 (dbe,
2912 PREP_QUERY_GET_SYMBOL_SCOPE_DEFINITION_ID,
2913 "tokenname",
2914 value1,
2915 "objectname",
2916 value2)) < 0)
2918 if (free_token_name)
2919 g_free (token_name);
2921 gda_value_free (value1);
2922 gda_value_free (value2);
2923 return FALSE;
2925 gda_value_free (value1);
2926 gda_value_free (value2);
2928 if (free_token_name)
2929 g_free (token_name);
2931 /* if we reach this point we should have a good scope_id.
2932 * Go on with symbol updating.
2935 value_id2 = gda_data_model_get_value_at_col_name (data, "symbol_referer_id",
2936 data_row);
2937 symbol_id = g_value_get_int (value_id2);
2940 if ((query = sdb_engine_get_query_by_id (dbe,
2941 PREP_QUERY_UPDATE_SYMBOL_SCOPE_ID))
2942 == NULL)
2944 g_warning ("query is null");
2945 return -1;
2948 if (GDA_QUERY_TYPE_NON_PARSED_SQL
2949 == gda_query_get_query_type ((GdaQuery *) query))
2951 g_warning ("non parsed sql error");
2952 return;
2955 if ((par_list = gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
2957 g_warning ("par_list is NULL!\n");
2958 return;
2961 /* scopeid parameter */
2962 if ((param = gda_parameter_list_find_param (par_list, "scopeid")) == NULL)
2964 g_warning ("param scopeid is NULL from pquery!");
2965 return;
2968 value = gda_value_new (G_TYPE_INT);
2969 g_value_set_int (value, scope_id);
2970 gda_parameter_set_value (param, value);
2972 /* symbolid parameter */
2973 if ((param = gda_parameter_list_find_param (par_list, "symbolid")) == NULL)
2975 g_warning ("param symbolid is NULL from pquery!");
2976 return;
2979 gda_value_reset_with_type (value, G_TYPE_INT);
2980 g_value_set_int (value, symbol_id);
2981 gda_parameter_set_value (param, value);
2982 gda_value_free (value);
2984 /* execute the query with parametes just set */
2985 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
2987 return TRUE;
2992 * @param data Must be filled with some values. It must have num_rows > 0
2993 * @note *CALL THIS BEFORE second_pass_update_heritage ()*
2994 * @note *DO NOT FREE data* inside this function.
2996 static void
2997 sdb_engine_second_pass_update_scope (SymbolDBEngine * dbe, GdaDataModel * data)
3000 * Fill up the scope.
3001 * The case: "my_foo_func_1" is the name of the current tag parsed.
3002 * Suppose we have a namespace MyFooNamespace, under which is declared
3003 * a class MyFooClass. Under that class there are some funcs like
3004 * my_foo_func_1 () etc. ctags will present us this info about
3005 * my_foo_func_1 ():
3006 * "class : MyFooNamespace::MyFooClass"
3007 * but hey! We don't need to know the namespace here, we just want to
3008 * know that my_foo_func_1 is in the scope of MyFooClass. That one will
3009 * then be mapped inside MyFooNamespace, but that's another thing.
3010 * Go on with the parsing then.
3012 gint i;
3014 for (i = 0; i < gda_data_model_get_n_rows (data); i++)
3016 GValue *value;
3018 if ((value =
3019 (GValue *) gda_data_model_get_value_at_col_name (data,
3020 "field_class",
3021 i)) != NULL)
3023 sdb_engine_second_pass_update_scope_1 (dbe, data, i, "class",
3024 value);
3027 if ((value =
3028 (GValue *) gda_data_model_get_value_at_col_name (data,
3029 "field_struct",
3030 i)) != NULL)
3032 sdb_engine_second_pass_update_scope_1 (dbe, data, i, "struct",
3033 value);
3036 if ((value =
3037 (GValue *) gda_data_model_get_value_at_col_name (data,
3038 "field_typeref",
3039 i)) != NULL)
3041 /* this is a "typedef", not a "typeref". */
3042 sdb_engine_second_pass_update_scope_1 (dbe, data, i, "typedef",
3043 value);
3046 if ((value =
3047 (GValue *) gda_data_model_get_value_at_col_name (data,
3048 "field_enum",
3049 i)) != NULL)
3051 sdb_engine_second_pass_update_scope_1 (dbe, data, i, "enum", value);
3054 if ((value =
3055 (GValue *) gda_data_model_get_value_at_col_name (data,
3056 "field_union",
3057 i)) != NULL)
3059 sdb_engine_second_pass_update_scope_1 (dbe, data, i, "union",
3060 value);
3063 if ((value =
3064 (GValue *) gda_data_model_get_value_at_col_name (data,
3065 "field_namespace",
3066 i)) != NULL)
3068 sdb_engine_second_pass_update_scope_1 (dbe, data, i, "namespace",
3069 value);
3076 * @param data Must be filled with some values. It must have num_rows > 0
3077 * @note *CALL THIS AFTER second_pass_update_scope ()*
3079 static void
3080 sdb_engine_second_pass_update_heritage (SymbolDBEngine * dbe,
3081 GdaDataModel * data)
3083 gint i;
3084 SymbolDBEnginePriv *priv;
3086 g_return_if_fail (dbe != NULL);
3088 priv = dbe->priv;
3090 for (i = 0; i < gda_data_model_get_n_rows (data); i++)
3092 const GValue *value;
3093 const gchar *inherits;
3094 gchar *item;
3095 gchar **inherits_list;
3096 gint j;
3098 value = gda_data_model_get_value_at_col_name (data,
3099 "field_inherits", i);
3100 inherits = g_value_get_string (value);
3102 /* there can be multiple inheritance. Check that. */
3103 inherits_list = g_strsplit (inherits, ",", 0);
3105 if (inherits_list != NULL)
3106 DEBUG_PRINT ("inherits %s\n", inherits);
3108 /* retrieve as much info as we can from the items */
3109 for (j = 0; j < g_strv_length (inherits_list); j++)
3111 gchar **namespaces;
3112 gchar *klass_name;
3113 gchar *namespace_name;
3114 gint namespaces_length;
3115 gint base_klass_id;
3116 gint derived_klass_id;
3117 const GValue *value, *value2;
3119 item = inherits_list[j];
3120 DEBUG_PRINT ("heritage %s\n", item);
3122 /* A item may have this string form:
3123 * MyFooNamespace1::MyFooNamespace2::MyFooClass
3124 * We should find the field 'MyFooNamespace2' because it's the one
3125 * that is reachable by the scope_id value of the symbol.
3128 namespaces = g_strsplit (item, "::", 0);
3129 namespaces_length = g_strv_length (namespaces);
3131 if (namespaces_length > 1)
3133 /* this is the case in which we have the case with
3134 * namespace + class
3136 namespace_name = g_strdup (namespaces[namespaces_length - 2]);
3137 klass_name = g_strdup (namespaces[namespaces_length - 1]);
3139 else
3141 /* have a last check before setting namespace_name to null.
3142 * check whether the field_namespace is void or not.
3144 const GValue *namespace_value;
3145 const gchar *tmp_namespace;
3146 gchar **tmp_namespace_array = NULL;
3147 gint tmp_namespace_length;
3149 namespace_value =
3150 gda_data_model_get_value_at_col_name (data,
3151 "field_namespace", i);
3152 tmp_namespace = g_value_get_string (namespace_value);
3153 if (tmp_namespace != NULL)
3155 tmp_namespace_array = g_strsplit (tmp_namespace, "::", 0);
3156 tmp_namespace_length = g_strv_length (tmp_namespace_array);
3158 if (tmp_namespace_length > 0)
3159 namespace_name =
3160 g_strdup (tmp_namespace_array
3161 [tmp_namespace_length - 1]);
3162 else
3163 namespace_name = NULL;
3165 else
3167 namespace_name = NULL;
3170 klass_name = g_strdup (namespaces[namespaces_length - 1]);
3172 g_strfreev (tmp_namespace_array);
3175 g_strfreev (namespaces);
3177 /* get the derived_klass_id. It should be the
3178 * symbol_referer_id field into __tmp_heritage_scope table
3180 if ((value = (GValue *) gda_data_model_get_value_at (data,
3181 1, i)) != NULL)
3183 derived_klass_id = g_value_get_int (value);
3185 else
3187 derived_klass_id = 0;
3190 /* ok, search for the symbol_id of the base class */
3191 if (namespace_name == NULL)
3193 GValue *value1;
3195 value1 = gda_value_new (G_TYPE_STRING);
3196 g_value_set_string (value1, klass_name);
3198 if ((base_klass_id =
3199 sdb_engine_get_table_id_by_unique_name (dbe,
3200 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME,
3201 "klassname",
3202 value1)) < 0)
3204 gda_value_free (value1);
3205 continue;
3207 gda_value_free (value1);
3209 else
3211 /* FIXME:
3212 when Libgda will parse correctly the PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME_AND_NAMESPACE
3213 query please uncomment this section and let the prepared statements do their
3214 work.
3215 GValue *value1;
3216 GValue *value2;
3218 value1 = gda_value_new (G_TYPE_STRING);
3219 g_value_set_string (value1, klass_name);
3221 value2 = gda_value_new (G_TYPE_STRING);
3222 g_value_set_string (value2, namespace_name);
3224 DEBUG_PRINT ("value1 : %s value2 : %s", klass_name, namespace_name);
3225 if ((base_klass_id =
3226 sdb_engine_get_table_id_by_unique_name2 (dbe,
3227 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME_AND_NAMESPACE,
3228 "klassname",
3229 value1,
3230 "namespacename",
3231 value2)) < 0)
3233 gda_value_free (value1);
3234 gda_value_free (value2);
3235 continue;
3237 gda_value_free (value1);
3238 gda_value_free (value2);
3240 GValue *value1;
3241 GdaCommand *command;
3242 GdaDataModel *base_data;
3243 gchar *query_str;
3244 query_str =
3245 g_strdup_printf ("SELECT symbol_id FROM symbol JOIN scope ON "
3246 "symbol.scope_id=scope.scope_id JOIN sym_type ON "
3247 "scope.type_id=sym_type.type_id WHERE "
3248 "symbol.name='%s' AND scope.scope='%s' AND "
3249 "sym_type.type='namespace'",
3250 klass_name, namespace_name);
3252 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
3253 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
3255 if ( (base_data =
3256 gda_connection_execute_select_command (priv->db_connection,
3257 command, NULL,
3258 NULL)) == NULL ||
3259 gda_data_model_get_n_rows (base_data) <= 0 )
3261 gda_command_free (command);
3262 g_free (query_str);
3264 if (base_data != NULL)
3265 g_object_unref (base_data);
3267 continue;
3270 value1 = (GValue*)gda_data_model_get_value_at (base_data, 0, 0);
3271 base_klass_id = g_value_get_int (value1);
3272 DEBUG_PRINT ("found base_klass_id %d", base_klass_id );
3273 gda_command_free (command);
3274 g_free (query_str);
3276 if (base_data != NULL)
3277 g_object_unref (base_data);
3280 if (namespace_name)
3281 g_free (namespace_name);
3282 g_free (klass_name);
3284 DEBUG_PRINT ("gonna sdb_engine_add_new_heritage with "
3285 "base_klass_id %d, derived_klass_id %d", base_klass_id,
3286 derived_klass_id);
3287 sdb_engine_add_new_heritage (dbe, base_klass_id, derived_klass_id);
3290 g_strfreev (inherits_list);
3295 * Process the temporary table to update the symbols on scope and inheritance
3296 * fields.
3297 * *CALL THIS FUNCTION ONLY AFTER HAVING PARSED ALL THE TAGS ONCE*
3300 static void
3301 sdb_engine_second_pass_do (SymbolDBEngine * dbe)
3303 GObject *obj;
3304 const GdaQuery *query1, *query2, *query3;
3306 /* prepare for scope second scan */
3307 if ((query1 =
3308 sdb_engine_get_query_by_id (dbe,
3309 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE))
3310 == NULL)
3312 g_warning ("query is null");
3313 return;
3316 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
3317 gda_query_get_query_type ((GdaQuery *) query1))
3319 g_warning ("non parsed sql error");
3320 return;
3323 /* execute the query */
3324 obj = G_OBJECT (gda_query_execute ((GdaQuery *) query1, NULL, FALSE, NULL));
3326 if (!GDA_IS_DATA_MODEL (obj) ||
3327 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj)) <= 0)
3330 if (obj != NULL)
3331 g_object_unref (obj);
3332 obj = NULL;
3334 else
3336 sdb_engine_second_pass_update_scope (dbe, GDA_DATA_MODEL (obj));
3339 if (obj != NULL)
3340 g_object_unref (obj);
3342 /* prepare for heritage second scan */
3343 if ((query2 =
3344 sdb_engine_get_query_by_id (dbe,
3345 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE_WITH_INHERITS))
3346 == NULL)
3348 g_warning ("query is null");
3349 return;
3352 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
3353 gda_query_get_query_type ((GdaQuery *) query2))
3355 g_warning ("non parsed sql error");
3356 return;
3359 /* execute the query */
3360 obj = G_OBJECT (gda_query_execute ((GdaQuery *) query2, NULL, FALSE, NULL));
3362 if (!GDA_IS_DATA_MODEL (obj) ||
3363 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj)) <= 0)
3365 if (obj != NULL)
3366 g_object_unref (obj);
3367 obj = NULL;
3369 else
3371 sdb_engine_second_pass_update_heritage (dbe, GDA_DATA_MODEL (obj));
3374 if (obj != NULL)
3375 g_object_unref (obj);
3378 /* clean tmp heritage table */
3379 if ((query3 =
3380 sdb_engine_get_query_by_id (dbe,
3381 PREP_QUERY_TMP_HERITAGE_DELETE_ALL))
3382 == NULL)
3384 g_warning ("query is null");
3385 return;
3388 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
3389 gda_query_get_query_type ((GdaQuery *) query3))
3391 g_warning ("non parsed sql error");
3392 return;
3395 /* execute the query */
3396 gda_query_execute ((GdaQuery *) query3, NULL, FALSE, NULL);
3399 /* base_prj_path can be NULL. In that case path info tag_entry will be taken
3400 * as an absolute path.
3401 * fake_file can be used when a buffer updating is being executed. In that
3402 * particular case both base_prj_path and tag_entry->file will be ignored.
3403 * fake_file is real_path of file on disk
3405 static gint
3406 sdb_engine_add_new_symbol (SymbolDBEngine * dbe, tagEntry * tag_entry,
3407 gchar * base_prj_path, gchar * fake_file,
3408 gboolean sym_update)
3411 CREATE TABLE symbol (symbol_id integer PRIMARY KEY AUTOINCREMENT,
3412 file_defined_id integer not null REFERENCES file (file_id),
3413 name varchar (256) not null,
3414 file_position integer,
3415 is_file_scope integer,
3416 signature varchar (256),
3417 scope_definition_id integer,
3418 scope_id integer,
3419 type_id integer REFERENCES sym_type (type_id),
3420 kind_id integer REFERENCES sym_kind (sym_kind_id),
3421 access_kind_id integer REFERENCES sym_access (sym_access_id),
3422 implementation_kind_id integer REFERENCES sym_implementation
3423 (sym_impl_id)
3426 SymbolDBEnginePriv *priv;
3427 const GdaQuery *query;
3428 GdaParameterList *par_list;
3429 GdaParameter *param;
3430 const gchar *tmp_str;
3431 gint table_id, symbol_id;
3432 gchar *query_str;
3433 gint file_defined_id = 0;
3434 gchar name[256];
3435 gint file_position = 0;
3436 gint is_file_scope = 0;
3437 gchar signature[256];
3438 gint scope_definition_id = 0;
3439 gint scope_id = 0;
3440 gint type_id = 0;
3441 gint kind_id = 0;
3442 gint access_kind_id = 0;
3443 gint implementation_kind_id = 0;
3444 GValue *value, *value1, *value2, *value3;
3445 gboolean sym_was_updated = FALSE;
3447 gint update_flag;
3449 g_return_val_if_fail (dbe != NULL, -1);
3450 priv = dbe->priv;
3452 /* keep it at 0 if sym_update == false */
3453 if (sym_update == FALSE)
3454 update_flag = 0;
3455 else
3456 update_flag = 1;
3458 g_return_val_if_fail (tag_entry != NULL, -1);
3460 value = gda_value_new (G_TYPE_STRING);
3461 if (base_prj_path != NULL)
3463 /* in this case fake_file will be ignored. */
3465 /* we expect here an absolute path */
3466 g_value_set_string (value,
3467 tag_entry->file + strlen (base_prj_path) );
3469 else
3471 /* check whether the fake_file can substitute the tag_entry->file one */
3472 if (fake_file == NULL)
3473 g_value_set_string (value, tag_entry->file);
3474 else
3475 g_value_set_string (value, fake_file);
3478 if ((file_defined_id = sdb_engine_get_table_id_by_unique_name (dbe,
3479 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME,
3480 "filepath",
3481 value)) < 0)
3483 /* if we arrive here there should be some sync problems between the filenames
3484 * in database and the ones in the ctags files. We trust in db's ones,
3485 * so we'll just return here.
3487 g_warning ("sync problems between db and ctags filenames entries. "
3488 "File was %s (base_path: %s, fake_file: %s, tag_file: %s)",
3489 g_value_get_string (value), base_prj_path, fake_file,
3490 tag_entry->file);
3491 gda_value_free (value);
3492 return -1;
3496 /* parse the entry name */
3497 if (strlen (tag_entry->name) > sizeof (name))
3499 printf
3500 ("fatal error when inserting symbol, name of symbol is too big.\n");
3501 gda_value_free (value);
3502 return -1;
3504 else
3506 memset (name, 0, sizeof (name));
3507 memcpy (name, tag_entry->name, strlen (tag_entry->name));
3510 file_position = tag_entry->address.lineNumber;
3511 is_file_scope = tag_entry->fileScope;
3513 memset (signature, 0, sizeof (signature));
3514 if ((tmp_str = tagsField (tag_entry, "signature")) != NULL)
3516 if (strlen (tmp_str) > sizeof (signature))
3518 memcpy (signature, tmp_str, sizeof (signature));
3520 else
3522 memcpy (signature, tmp_str, strlen (tmp_str));
3526 type_id = sdb_engine_add_new_sym_type (dbe, tag_entry);
3528 /* scope_definition_id tells what scope this symbol defines
3529 * this call *MUST BE DONE AFTER* sym_type table population.
3531 scope_definition_id = sdb_engine_add_new_scope_definition (dbe, tag_entry);
3533 /* the container scopes can be: union, struct, typeref, class, namespace etc.
3534 * this field will be parse in the second pass.
3536 scope_id = 0;
3538 kind_id = sdb_engine_add_new_sym_kind (dbe, tag_entry);
3539 access_kind_id = sdb_engine_add_new_sym_access (dbe, tag_entry);
3540 implementation_kind_id =
3541 sdb_engine_add_new_sym_implementation (dbe, tag_entry);
3543 /* ok: was the symbol updated [at least on it's type_id/name]?
3544 * There are 3 cases:
3545 * #1. The symbol remain the same [at least on unique index key]. We will
3546 * perform only a simple update.
3547 * #2. The symbol has changed: at least on name/type/file. We will insert a
3548 * new symbol on table 'symbol'. Deletion of old one will take place
3549 * at a second stage, when a delete of all symbols with
3550 * 'tmp_flag = 0' will be done.
3551 * #3. The symbol has been deleted. As above it will be deleted at
3552 * a second stage because of the 'tmp_flag = 0'. Triggers will remove
3553 * also scope_ids and other things.
3556 value1 = gda_value_new (G_TYPE_STRING);
3557 g_value_set_string (value1, name);
3559 value2 = gda_value_new (G_TYPE_INT);
3560 g_value_set_int (value2, file_defined_id);
3562 value3 = gda_value_new (G_TYPE_INT);
3563 g_value_set_int (value3, type_id);
3565 if ((symbol_id = sdb_engine_get_table_id_by_unique_name3 (dbe,
3566 PREP_QUERY_GET_SYMBOL_ID_BY_UNIQUE_INDEX_KEY,
3567 "symname", value1,
3568 "filedefid",value2,
3569 "typeid", value3)) <= 0)
3571 /* case 2 and 3 */
3572 /* DEBUG_PRINT ("inserting new symbol: %s", name);*/
3573 sym_was_updated = FALSE;
3575 gda_value_free (value1);
3576 gda_value_free (value2);
3577 gda_value_free (value3);
3579 /* create specific query for a fresh new symbol */
3580 if ((query = sdb_engine_get_query_by_id (dbe, PREP_QUERY_SYMBOL_NEW))
3581 == NULL)
3583 g_warning ("query is null");
3584 return -1;
3587 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
3588 gda_query_get_query_type ((GdaQuery *) query))
3590 g_warning ("non parsed sql error");
3591 gda_value_free (value);
3592 return -1;
3595 if ((par_list =
3596 gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
3598 g_warning ("par_list is NULL!\n");
3599 gda_value_free (value);
3600 return -1;
3603 /* filedefid parameter */
3604 if ((param =
3605 gda_parameter_list_find_param (par_list, "filedefid")) == NULL)
3607 g_warning ("param filedefid is NULL from pquery!");
3608 gda_value_free (value);
3609 return -1;
3612 gda_value_reset_with_type (value, G_TYPE_INT);
3613 g_value_set_int (value, file_defined_id);
3614 gda_parameter_set_value (param, value);
3616 /* name parameter */
3617 if ((param = gda_parameter_list_find_param (par_list, "name")) == NULL)
3619 g_warning ("param name is NULL from pquery!");
3620 gda_value_free (value);
3621 return -1;
3624 gda_value_reset_with_type (value, G_TYPE_STRING);
3625 g_value_set_string (value, name);
3626 gda_parameter_set_value (param, value);
3628 /* fileposition parameter */
3629 if ((param =
3630 gda_parameter_list_find_param (par_list, "fileposition")) == NULL)
3632 g_warning ("param fileposition is NULL from pquery!");
3633 gda_value_free (value);
3634 return -1;
3637 gda_value_reset_with_type (value, G_TYPE_INT);
3638 g_value_set_int (value, file_position);
3639 gda_parameter_set_value (param, value);
3642 /* typeid parameter */
3643 if ((param =
3644 gda_parameter_list_find_param (par_list, "typeid")) == NULL)
3646 g_warning ("param typeid is NULL from pquery!");
3647 gda_value_free (value);
3648 return -1;
3651 gda_value_reset_with_type (value, G_TYPE_INT);
3652 g_value_set_int (value, type_id);
3653 gda_parameter_set_value (param, value);
3655 else
3657 /* case 1 */
3658 /* DEBUG_PRINT ("updating symbol: %s", name);*/
3659 sym_was_updated = TRUE;
3661 gda_value_free (value1);
3662 gda_value_free (value2);
3663 gda_value_free (value3);
3665 /* create specific query for a fresh new symbol */
3666 if ((query = sdb_engine_get_query_by_id (dbe,
3667 PREP_QUERY_UPDATE_SYMBOL_ALL))
3668 == NULL)
3670 g_warning ("query is null");
3671 return -1;
3674 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
3675 gda_query_get_query_type ((GdaQuery *) query))
3677 g_warning ("non parsed sql error");
3678 gda_value_free (value);
3679 return -1;
3682 if ((par_list =
3683 gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
3685 g_warning ("par_list is NULL!\n");
3686 gda_value_free (value);
3687 return -1;
3690 /* isfilescope parameter */
3691 if ((param = gda_parameter_list_find_param (par_list, "symbolid"))
3692 == NULL)
3694 g_warning ("param isfilescope is NULL from pquery!");
3695 gda_value_free (value);
3696 return -1;
3699 gda_value_reset_with_type (value, G_TYPE_INT);
3700 g_value_set_int (value, symbol_id);
3701 gda_parameter_set_value (param, value);
3704 /* common params */
3706 /* isfilescope parameter */
3707 if ((param =
3708 gda_parameter_list_find_param (par_list, "isfilescope")) == NULL)
3710 g_warning ("param isfilescope is NULL from pquery!");
3711 gda_value_free (value);
3712 return -1;
3715 gda_value_reset_with_type (value, G_TYPE_INT);
3716 g_value_set_int (value, is_file_scope);
3717 gda_parameter_set_value (param, value);
3719 /* signature parameter */
3720 if ((param = gda_parameter_list_find_param (par_list, "signature")) == NULL)
3722 g_warning ("param signature is NULL from pquery!");
3723 gda_value_free (value);
3724 return -1;
3727 gda_value_reset_with_type (value, G_TYPE_STRING);
3728 g_value_set_string (value, signature);
3729 gda_parameter_set_value (param, value);
3731 /* scopedefinitionid parameter */
3732 if ((param =
3733 gda_parameter_list_find_param (par_list, "scopedefinitionid")) == NULL)
3735 g_warning ("param scopedefinitionid is NULL from pquery!");
3736 gda_value_free (value);
3737 return -1;
3740 gda_value_reset_with_type (value, G_TYPE_INT);
3741 g_value_set_int (value, scope_definition_id);
3742 gda_parameter_set_value (param, value);
3744 /* scopeid parameter */
3745 if ((param = gda_parameter_list_find_param (par_list, "scopeid")) == NULL)
3747 g_warning ("param scopeid is NULL from pquery!");
3748 gda_value_free (value);
3749 return -1;
3752 gda_value_reset_with_type (value, G_TYPE_INT);
3753 g_value_set_int (value, scope_id);
3754 gda_parameter_set_value (param, value);
3756 /* kindid parameter */
3757 if ((param = gda_parameter_list_find_param (par_list, "kindid")) == NULL)
3759 g_warning ("param kindid is NULL from pquery!");
3760 gda_value_free (value);
3761 return -1;
3764 gda_value_reset_with_type (value, G_TYPE_INT);
3765 g_value_set_int (value, kind_id);
3766 gda_parameter_set_value (param, value);
3768 /* accesskindid parameter */
3769 if ((param =
3770 gda_parameter_list_find_param (par_list, "accesskindid")) == NULL)
3772 g_warning ("param accesskindid is NULL from pquery!");
3773 gda_value_free (value);
3774 return -1;
3777 gda_value_reset_with_type (value, G_TYPE_INT);
3778 g_value_set_int (value, access_kind_id);
3779 gda_parameter_set_value (param, value);
3781 /* implementationkindid parameter */
3782 if ((param =
3783 gda_parameter_list_find_param (par_list,
3784 "implementationkindid")) == NULL)
3786 g_warning ("param implementationkindid is NULL from pquery!");
3787 gda_value_free (value);
3788 return -1;
3791 gda_value_reset_with_type (value, G_TYPE_INT);
3792 g_value_set_int (value, implementation_kind_id);
3793 gda_parameter_set_value (param, value);
3795 /* updateflag parameter */
3796 if ((param =
3797 gda_parameter_list_find_param (par_list, "updateflag")) == NULL)
3799 g_warning ("param updateflag is NULL from pquery!");
3800 gda_value_free (value);
3801 return -1;
3804 gda_value_reset_with_type (value, G_TYPE_INT);
3805 g_value_set_int (value, update_flag);
3806 gda_parameter_set_value (param, value);
3807 gda_value_free (value);
3809 /* execute the query with parametes just set */
3810 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
3812 if (sym_was_updated == FALSE)
3814 table_id = sdb_engine_get_last_insert_id (dbe);
3816 /* This is a wrong place to emit the symbol-updated signal. Infact
3817 * db is in a inconsistent state, e.g. inheritance references are still
3818 * *not* calculated.
3819 * So add the symbol id into a queue that will be parsed once and emitted.
3821 /* g_signal_emit (dbe, signals[SYMBOL_INSERTED], 0, table_id); */
3822 g_async_queue_push (priv->inserted_symbols_id, (gpointer) table_id);
3824 else
3826 table_id = symbol_id;
3828 /* This is a wrong place to emit the symbol-updated signal. Infact
3829 * db is in a inconsistent state, e.g. inheritance references are still
3830 * *not* calculated.
3831 * So add the symbol id into a queue that will be parsed once and emitted.
3833 /* g_signal_emit (dbe, signals[SYMBOL_UPDATED], 0, table_id); */
3834 g_async_queue_push (priv->updated_symbols_id, (gpointer) table_id);
3837 /* before returning the table_id we have to fill some infoz on temporary tables
3838 * so that in a second pass we can parse also the heritage and scope fields.
3840 sdb_engine_add_new_tmp_heritage_scope (dbe, tag_entry, table_id);
3842 return table_id;
3847 * Select * from __tmp_removed and emits removed signals.
3849 void
3850 sdb_engine_detects_removed_ids (SymbolDBEngine *dbe)
3852 const GdaQuery *query, *query2;
3853 SymbolDBEnginePriv *priv;
3854 GValue *value;
3855 GObject *obj;
3856 gint i;
3857 gint num_rows;
3859 g_return_if_fail (dbe != NULL);
3861 priv = dbe->priv;
3863 /* ok, now we should read from __tmp_removed all the symbol ids which have
3864 * been removed, and emit a signal
3866 if ((query = sdb_engine_get_query_by_id (dbe,
3867 PREP_QUERY_GET_REMOVED_IDS))
3868 == NULL)
3870 g_warning ("query is null");
3871 return;
3874 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
3875 gda_query_get_query_type ((GdaQuery *) query))
3877 g_warning ("non parsed sql error");
3878 return;
3881 obj = G_OBJECT (gda_query_execute ((GdaQuery *) query, NULL, FALSE,
3882 NULL));
3884 if (GDA_IS_DATA_MODEL (obj))
3886 if ((num_rows = gda_data_model_get_n_rows (GDA_DATA_MODEL (obj))) <= 0)
3888 g_object_unref (obj);
3889 return;
3892 else
3894 if (obj != NULL)
3895 g_object_unref (obj);
3896 return;
3899 /* get and parse the results. */
3900 for (i = 0; i < num_rows; i++)
3902 const GValue *val;
3903 gint tmp;
3904 val = gda_data_model_get_value_at (GDA_DATA_MODEL (obj), 0, i);
3905 tmp = g_value_get_int (val);
3907 g_signal_emit (dbe, signals[SYMBOL_REMOVED], 0, tmp);
3910 g_object_unref (obj);
3912 /* let's clean the tmp_table */
3913 if ((query2 = sdb_engine_get_query_by_id (dbe,
3914 PREP_QUERY_TMP_REMOVED_DELETE_ALL))
3915 == NULL)
3917 g_warning ("query is null");
3918 return;
3921 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
3922 gda_query_get_query_type ((GdaQuery *) query2))
3924 g_warning ("non parsed sql error");
3925 return;
3928 /* bye bye */
3929 gda_query_execute ((GdaQuery *) query2, NULL, FALSE, NULL);
3934 * WARNING: do not use this function thinking that it would do a scan of symbols
3935 * too. Use symbol_db_engine_update_files_symbols () instead. This one will set
3936 * up some things on db, like removing the 'old' files which have not been
3937 * updated.
3939 static gboolean
3940 sdb_engine_update_file (SymbolDBEngine * dbe, const gchar * file_on_db)
3942 const GdaQuery *query;
3943 gchar *query_str;
3944 GdaParameterList *par_list;
3945 GdaParameter *param;
3946 GValue *value;
3947 gint i;
3948 SymbolDBEnginePriv *priv;
3950 g_return_if_fail (dbe != NULL);
3952 priv = dbe->priv;
3954 if (symbol_db_engine_is_project_opened (dbe, priv->project_name) == FALSE)
3956 g_warning ("project is not opened");
3957 return FALSE;
3961 /* if we're updating symbols we must do some other operations on db
3962 * symbols, like remove the ones which don't have an update_flag = 1
3963 * per updated file.
3966 /* good. Go on with removing of old symbols, marked by a
3967 * update_flag = 0.
3970 /* FIXME: libgda 3.0 doesn't have support for JOIN keyword at all on
3971 * prepared statements.
3972 * Said this we cannot expect to run queries on a really performant
3973 * way.
3976 /* Triggers will take care of updating/deleting connected symbols
3977 * tuples, like sym_kind, sym_type etc */
3978 query_str = g_strdup_printf ("DELETE FROM symbol WHERE "
3979 "file_defined_id = (SELECT file_id FROM file "
3980 "WHERE file_path = \"%s\") AND update_flag = 0",
3981 file_on_db);
3983 sdb_engine_execute_non_select_sql (dbe, query_str);
3984 g_free (query_str);
3986 /* emits removed symbols signals */
3987 sdb_engine_detects_removed_ids (dbe);
3989 /* reset the update_flag to 0 */
3990 query_str = g_strdup_printf ("UPDATE symbol SET update_flag = 0 "
3991 "WHERE file_defined_id = (SELECT file_id FROM file WHERE "
3992 "file_path = \"%s\")", file_on_db);
3994 sdb_engine_execute_non_select_sql (dbe, query_str);
3995 g_free (query_str);
3997 /* last but not least, update the file analize_time */
3998 if ((query = sdb_engine_get_query_by_id (dbe,
3999 PREP_QUERY_UPDATE_FILE_ANALIZE_TIME))
4000 == NULL)
4002 g_warning ("query is null");
4003 return FALSE;
4006 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
4007 gda_query_get_query_type ((GdaQuery *) query))
4009 g_warning ("non parsed sql error");
4010 return FALSE;
4013 if ((par_list = gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
4015 g_warning ("par_list is NULL!\n");
4016 return FALSE;
4019 /* filepath parameter */
4020 if ((param = gda_parameter_list_find_param (par_list, "filepath")) == NULL)
4022 g_warning ("param filepath is NULL from pquery!");
4023 return FALSE;
4026 value = gda_value_new (G_TYPE_STRING);
4027 g_value_set_string (value, file_on_db);
4028 gda_parameter_set_value (param, value);
4030 gda_value_free (value);
4031 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
4033 return TRUE;
4037 * @param data is a GPtrArray *files_to_scan
4038 * It will be freed when this callback will be called.
4040 static void
4041 on_scan_update_files_symbols_end (SymbolDBEngine * dbe, GPtrArray* data)
4043 SymbolDBEnginePriv *priv;
4044 GPtrArray *files_to_scan;
4045 gint i;
4047 DEBUG_PRINT ("on_scan_update_files_symbols_end ();");
4049 g_return_if_fail (dbe != NULL);
4050 g_return_if_fail (data != NULL);
4052 priv = dbe->priv;
4053 files_to_scan = (GPtrArray *) data;
4055 DEBUG_PRINT ("files_to_scan->len %d", files_to_scan->len);
4057 for (i = 0; i < files_to_scan->len; i++)
4059 gchar *node = (gchar *) g_ptr_array_index (files_to_scan, i);
4061 /* DEBUG_PRINT ("processing updating node: %s, data_source: %s", node,
4062 priv->data_source);
4063 DEBUG_PRINT ("processing updating for file %s", node +
4064 strlen (priv->data_source));*/
4066 /* clean the db from old un-updated with the last update step () */
4067 if (sdb_engine_update_file (dbe, node +
4068 strlen (priv->data_source)) == FALSE)
4070 g_warning ("Error processing file %s", node +
4071 strlen (priv->data_source) );
4072 return;
4074 g_free (node);
4077 g_signal_handlers_disconnect_by_func (dbe, on_scan_update_files_symbols_end,
4078 files_to_scan);
4080 /* free the GPtrArray. */
4081 DEBUG_PRINT ("free the files_to_scan");
4082 g_ptr_array_free (files_to_scan, TRUE);
4083 data = files_to_scan = NULL;
4084 DEBUG_PRINT ("done");
4088 /* Update symbols of saved files.
4089 * WARNING: files_path and it's contents will be freed on
4090 * on_scan_update_files_symbols_end () callback.
4092 gboolean
4093 symbol_db_engine_update_files_symbols (SymbolDBEngine * dbe, gchar * project,
4094 GPtrArray * files_path /*,
4095 * gchar *language */ ,
4096 gboolean update_prj_analize_time)
4098 SymbolDBEnginePriv *priv;
4100 priv = dbe->priv;
4102 DEBUG_PRINT ("symbol_db_engine_update_files_symbols ()");
4103 g_return_val_if_fail (priv->db_connection != NULL, FALSE);
4104 g_return_val_if_fail (project != NULL, FALSE);
4106 if (symbol_db_engine_is_project_opened (dbe, project) == FALSE)
4108 g_warning ("project is not opened");
4109 return FALSE;
4112 /* data will be freed when callback will be called. The signal will be
4113 * disconnected too, don't worry about disconneting it by hand.
4115 g_signal_connect (G_OBJECT (dbe), "scan-end",
4116 G_CALLBACK (on_scan_update_files_symbols_end), files_path);
4118 sdb_engine_scan_files_1 (dbe, files_path, NULL, TRUE);
4120 /* if true, we'll update the project scanning time too.
4121 * warning: project time scanning won't could be set before files one.
4122 * This why we'll fork the process calling sdb_engine_scan_files ()
4124 if (update_prj_analize_time == TRUE)
4126 const GdaQuery *query;
4127 GdaParameterList *par_list;
4128 GdaParameter *param;
4129 GValue *value;
4131 /* and the project analize_time */
4132 if ((query = sdb_engine_get_query_by_id (dbe,
4133 PREP_QUERY_UPDATE_PROJECT_ANALIZE_TIME))
4134 == NULL)
4136 g_warning ("query is null");
4137 return;
4140 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
4141 gda_query_get_query_type ((GdaQuery *) query))
4143 g_warning ("non parsed sql error");
4144 return;
4147 if ((par_list =
4148 gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
4150 g_warning ("par_list is NULL!\n");
4151 return;
4154 /* prjname parameter */
4155 if ((param = gda_parameter_list_find_param (par_list, "prjname"))
4156 == NULL)
4158 g_warning ("param prjname is NULL from pquery!");
4159 return;
4162 value = gda_value_new (G_TYPE_STRING);
4163 g_value_set_string (value, priv->project_name);
4164 gda_parameter_set_value (param, value);
4166 gda_value_free (value);
4168 DEBUG_PRINT ("updating project analize_time");
4169 gda_query_execute ((GdaQuery *) query, par_list, FALSE, NULL);
4172 return TRUE;
4175 /* Update symbols of the whole project. It scans all file symbols etc.
4176 * FIXME: libgda does not support nested prepared queries like
4177 * PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_NAME. When it will do please
4178 * remember to update this function.
4180 gboolean
4181 symbol_db_engine_update_project_symbols (SymbolDBEngine * dbe, gchar * project /*,
4182 * gboolean force */ )
4184 const GdaQuery *query;
4185 GdaParameterList *par_list;
4186 GdaParameter *param;
4187 GValue *value;
4188 GObject *obj;
4189 gint project_id;
4190 gint num_rows;
4191 gint i;
4192 GPtrArray *files_to_scan;
4193 SymbolDBEnginePriv *priv;
4196 g_return_val_if_fail (dbe != NULL, FALSE);
4197 if (symbol_db_engine_is_project_opened (dbe, project) == FALSE)
4199 g_warning ("project is not opened");
4200 return FALSE;
4203 priv = dbe->priv;
4205 value = gda_value_new (G_TYPE_STRING);
4206 g_value_set_string (value, project);
4208 /* get project id */
4209 if ((project_id = sdb_engine_get_table_id_by_unique_name (dbe,
4210 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME,
4211 "prjname",
4212 value)) <= 0)
4214 gda_value_free (value);
4215 return FALSE;
4218 if ((query = sdb_engine_get_query_by_id (dbe,
4219 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_ID))
4220 == NULL)
4222 g_warning ("query is null");
4223 gda_value_free (value);
4224 return -1;
4227 if (GDA_QUERY_TYPE_NON_PARSED_SQL ==
4228 gda_query_get_query_type ((GdaQuery *) query))
4230 g_warning ("non parsed sql error");
4231 gda_value_free (value);
4232 return -1;
4235 if ((par_list = gda_query_get_parameter_list ((GdaQuery *) query)) == NULL)
4237 g_warning ("par_list is NULL!\n");
4238 gda_value_free (value);
4239 return -1;
4242 /* prjid parameter */
4243 if ((param = gda_parameter_list_find_param (par_list, "prjid")) == NULL)
4245 g_warning ("param prjname is NULL from pquery!");
4246 return -1;
4249 gda_value_reset_with_type (value, G_TYPE_INT);
4250 g_value_set_int (value, project_id);
4251 gda_parameter_set_value (param, value);
4253 /* execute the query with parametes just set */
4254 obj =
4255 G_OBJECT (gda_query_execute
4256 ((GdaQuery *) query, par_list, FALSE, NULL));
4258 if (!GDA_IS_DATA_MODEL (obj) ||
4259 (num_rows = gda_data_model_get_n_rows (GDA_DATA_MODEL (obj))) <= 0)
4262 g_message ("no rows");
4263 if (obj != NULL)
4264 g_object_unref (obj);
4265 obj = NULL;
4268 /* we don't need it anymore */
4269 gda_value_free (value);
4271 g_message ("got gda_data_model_get_n_rows (GDA_DATA_MODEL(obj)) %d",
4272 num_rows);
4274 /* initialize the array */
4275 files_to_scan = g_ptr_array_new ();
4277 /* we can now scan each filename entry to check the last modification time. */
4278 for (i = 0; i < num_rows; i++)
4280 const GValue *value, *value1;
4281 const gchar *file_name;
4282 gchar *file_abs_path;
4283 struct tm filetm;
4284 time_t db_file_time;
4285 gchar *date_string;
4286 gchar *abs_vfs_path;
4287 GnomeVFSHandle *handle;
4288 gchar timestamp[512];
4290 if ((value =
4291 gda_data_model_get_value_at_col_name (GDA_DATA_MODEL (obj),
4292 "file_path", i)) == NULL)
4294 continue;
4297 /* build abs path. */
4298 file_name = g_value_get_string (value);
4299 if (priv->data_source != NULL)
4301 abs_vfs_path = g_strdup_printf ("file://%s%s", priv->data_source,
4302 file_name);
4303 file_abs_path = g_strdup_printf ("%s%s", priv->data_source,
4304 file_name);
4306 else
4308 abs_vfs_path = g_strdup_printf ("file://%s", file_name);
4309 file_abs_path = g_strdup (file_name);
4312 GnomeVFSURI *uri = gnome_vfs_uri_new (abs_vfs_path);
4313 GnomeVFSFileInfo *file_info = gnome_vfs_file_info_new ();
4315 /* retrieve data/time info */
4316 if (gnome_vfs_open_uri (&handle, uri,
4317 GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM) !=
4318 GNOME_VFS_OK)
4320 g_message ("could not open URI %s", abs_vfs_path);
4321 gnome_vfs_uri_unref (uri);
4322 gnome_vfs_file_info_unref (file_info);
4323 g_free (abs_vfs_path);
4324 g_free (file_abs_path);
4325 continue;
4328 if (gnome_vfs_get_file_info_from_handle (handle, file_info,
4329 GNOME_VFS_FILE_INFO_DEFAULT) !=
4330 GNOME_VFS_OK)
4332 g_message ("cannot get file info from handle");
4333 gnome_vfs_close (handle);
4334 gnome_vfs_uri_unref (uri);
4335 gnome_vfs_file_info_unref (file_info);
4336 g_free (file_abs_path);
4337 continue;
4340 if ((value1 =
4341 gda_data_model_get_value_at_col_name (GDA_DATA_MODEL (obj),
4342 "analize_time", i)) == NULL)
4344 continue;
4347 /* weirdly we have a strange libgda behaviour here too.
4348 * as from ChangeLog GDA_TYPE_TIMESTAMP as SQLite does not impose a
4349 * known format for dates (there is no date datatype).
4350 * We have then to do some hackery to retrieve the date.
4352 date_string = (gchar *) g_value_get_string (value1);
4354 DEBUG_PRINT ("processing for upating symbol %s", file_name);
4355 DEBUG_PRINT ("date_string %s", date_string);
4357 /* fill a struct tm with the date retrieved by the string. */
4358 /* string is something like '2007-04-18 23:51:39' */
4359 memset (&filetm, 0, sizeof (struct tm));
4360 filetm.tm_year = atoi (date_string) - 1900;
4361 date_string += 5;
4362 filetm.tm_mon = atoi (date_string) - 1;
4363 date_string += 3;
4364 filetm.tm_mday = atoi (date_string);
4365 date_string += 3;
4366 filetm.tm_hour = atoi (date_string);
4367 date_string += 3;
4368 filetm.tm_min = atoi (date_string);
4369 date_string += 3;
4370 filetm.tm_sec = atoi (date_string);
4372 /* subtract one hour to the db_file_time. (why this?) */
4373 db_file_time = mktime (&filetm) - 3600;
4375 if (difftime (db_file_time, file_info->mtime) <= 0)
4377 g_message ("to be added! : %s", file_name);
4378 g_ptr_array_add (files_to_scan, file_abs_path);
4381 DEBUG_PRINT ("difftime %f", difftime (db_file_time, file_info->mtime));
4382 DEBUG_PRINT ("db_file_time %d - "
4383 "file_info->mtime %d "
4384 "file_info->ctime %d", db_file_time,
4385 file_info->mtime, file_info->ctime);
4387 gnome_vfs_close (handle);
4388 gnome_vfs_uri_unref (uri);
4389 gnome_vfs_file_info_unref (file_info);
4390 g_free (abs_vfs_path);
4391 /* no need to free file_abs_path, it's been added to files_to_scan */
4394 if (files_to_scan->len > 0)
4396 gint i;
4397 /* at the end let's the scanning function do its job */
4398 symbol_db_engine_update_files_symbols (dbe, project,
4399 files_to_scan, TRUE);
4404 /* Remove a file, together with its symbols, from a project. */
4405 gboolean
4406 symbol_db_engine_remove_file (SymbolDBEngine * dbe, const gchar * project,
4407 const gchar * file)
4409 gchar *query_str;
4410 SymbolDBEnginePriv *priv;
4412 g_return_val_if_fail (dbe != NULL, FALSE);
4413 if (symbol_db_engine_is_project_opened (dbe, project) == FALSE)
4415 g_warning ("project is not opened");
4416 return FALSE;
4419 priv = dbe->priv;
4421 if (strlen (file) < strlen (priv->data_source))
4423 g_warning ("wrong file");
4424 return FALSE;
4427 /* Triggers will take care of updating/deleting connected symbols
4428 * tuples, like sym_kind, sym_type etc */
4429 query_str = g_strdup_printf ("DELETE FROM file WHERE prj_id "
4430 "= (SELECT project_id FROM project WHERE project_name = '%s') AND "
4431 "file_path = '%s'", project, file + strlen (priv->data_source));
4433 /* DEBUG_PRINT ("symbol_db_engine_remove_file () : %s", query_str);*/
4434 sdb_engine_execute_non_select_sql (dbe, query_str);
4435 g_free (query_str);
4437 /* emits removed symbols signals */
4438 sdb_engine_detects_removed_ids (dbe);
4442 static void
4443 on_scan_update_buffer_end (SymbolDBEngine * dbe, gpointer data)
4445 SymbolDBEnginePriv *priv;
4446 GPtrArray *files_to_scan;
4447 gint i;
4449 g_return_if_fail (dbe != NULL);
4450 g_return_if_fail (data != NULL);
4452 priv = dbe->priv;
4453 files_to_scan = (GPtrArray *) data;
4456 DEBUG_PRINT ("files_to_scan->len %d", files_to_scan->len);
4457 for (i = 0; i < files_to_scan->len; i++)
4459 DEBUG_PRINT ("g_ptr_array_index (files_to_scan, %d); %s", i,
4460 g_ptr_array_index (files_to_scan, i));
4464 for (i = 0; i < files_to_scan->len; i++)
4466 gchar *node = (gchar *) g_ptr_array_index (files_to_scan, i);
4468 DEBUG_PRINT ("processing updating for file [on disk] %s, "
4469 "passed to on_scan_update_buffer_end (): ",
4470 node, node + strlen (priv->data_source));
4472 if (sdb_engine_update_file (dbe, node+
4473 strlen (priv->data_source)) == FALSE)
4475 g_warning ("Error processing file %s", node);
4476 return;
4478 g_free (node);
4481 g_signal_handlers_disconnect_by_func (dbe, on_scan_update_buffer_end,
4482 files_to_scan);
4484 /* free the GPtrArray. */
4485 DEBUG_PRINT ("free the files_to_scan");
4486 g_ptr_array_free (files_to_scan, TRUE);
4487 data = files_to_scan = NULL;
4488 DEBUG_PRINT ("done");
4491 static gboolean
4492 sdb_engine_scan_update_buffer (SymbolDBEngine * dbe, gchar * fake_file,
4493 gchar * text_buffer, gint buffer_size)
4495 return TRUE;
4499 /* Update symbols of a file by a memory-buffer to perform a real-time updating
4500 * of symbols.
4501 * real_files_list: full path on disk to 'real file' to update. e.g.
4502 * /home/foouser/fooproject/src/main.c
4504 gboolean
4505 symbol_db_engine_update_buffer_symbols (SymbolDBEngine * dbe, gchar * project,
4506 GPtrArray * real_files_list,
4507 const GPtrArray * text_buffers,
4508 const GPtrArray * buffer_sizes)
4510 SymbolDBEnginePriv *priv;
4511 gint i;
4513 DEBUG_PRINT ("symbol_db_engine_update_buffer_symbols ()");
4515 /* array that'll represent the /dev/shm/anjuta-XYZ files */
4516 GPtrArray *temp_files;
4517 GPtrArray *real_files_on_db;
4519 priv = dbe->priv;
4521 g_return_val_if_fail (priv->db_connection != NULL, FALSE);
4522 g_return_val_if_fail (project != NULL, FALSE);
4523 g_return_val_if_fail (real_files_list != NULL, FALSE);
4524 g_return_val_if_fail (text_buffers != NULL, FALSE);
4525 g_return_val_if_fail (buffer_sizes != NULL, FALSE);
4527 if (symbol_db_engine_is_project_opened (dbe, project) == FALSE)
4529 g_warning ("project is not opened");
4530 return FALSE;
4533 temp_files = g_ptr_array_new();
4534 real_files_on_db = g_ptr_array_new();
4536 /* obtain a GPtrArray with real_files on database */
4537 for (i=0; i < real_files_list->len; i++)
4539 gchar *new_node = (gchar*)g_ptr_array_index (real_files_list, i)
4540 + strlen(priv->data_source);
4541 DEBUG_PRINT ("real_file on db: %s", new_node);
4542 g_ptr_array_add (real_files_on_db, g_strdup (new_node));
4545 /* create a temporary file for each buffer */
4546 for (i=0; i < real_files_list->len; i++)
4548 FILE *shared_mem_file;
4549 const gchar *temp_buffer;
4550 gint shared_mem_fd;
4551 gint temp_size;
4552 gchar *temp_file;
4553 gchar *base_filename;
4554 const gchar *curr_real_file;
4556 curr_real_file = g_ptr_array_index (real_files_list, i);
4558 /* it's ok to have just the base filename to create the
4559 * target buffer one */
4560 base_filename = g_filename_display_basename (curr_real_file);
4562 temp_file = g_strdup_printf ("/anjuta-%d-%ld-%s", getpid (),
4563 time (NULL), base_filename);
4564 g_free (base_filename);
4566 DEBUG_PRINT ("my temp file is %s", temp_file);
4567 if ((shared_mem_fd =
4568 shm_open (temp_file, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) < 0)
4570 g_warning ("Error while trying to open a shared memory file. Be"
4571 "sure to have /dev/shm mounted with tmpfs");
4572 return FALSE;
4575 shared_mem_file = fdopen (shared_mem_fd, "w+b");
4577 DEBUG_PRINT ("shared fd %d", shared_mem_fd);
4578 DEBUG_PRINT ("shared file %d", shared_mem_file);
4579 DEBUG_PRINT ("temp_file %s", temp_file);
4581 temp_buffer = g_ptr_array_index (text_buffers, i);
4582 temp_size = (gint)g_ptr_array_index (buffer_sizes, i);
4583 fwrite (temp_buffer, sizeof(gchar), temp_size, shared_mem_file);
4584 fflush (shared_mem_file);
4585 fclose (shared_mem_file);
4587 /* add the temp file to the array. */
4588 g_ptr_array_add (temp_files, g_strdup_printf ("/dev/shm%s", temp_file));
4589 g_free (temp_file);
4593 /* data will be freed when callback will be called. The signal will be
4594 * disconnected too, don't worry about disconneting it by hand.
4596 g_signal_connect (G_OBJECT (dbe), "scan-end",
4597 G_CALLBACK (on_scan_update_buffer_end), real_files_list);
4599 sdb_engine_scan_files_1 (dbe, temp_files, real_files_on_db, TRUE);
4601 /* let's free the temp_files array */
4602 for (i=0; i < temp_files->len; i++)
4603 g_free (g_ptr_array_index (temp_files, i));
4605 g_ptr_array_free (temp_files, TRUE);
4607 /* and the real_files_on_db too */
4608 for (i=0; i < real_files_on_db->len; i++)
4609 g_free (g_ptr_array_index (real_files_on_db, i));
4611 g_ptr_array_free (real_files_on_db, TRUE);
4614 return TRUE;
4617 gboolean
4618 symbol_db_engine_is_locked (SymbolDBEngine * dbe)
4620 SymbolDBEnginePriv *priv;
4622 g_return_val_if_fail (dbe != NULL, FALSE);
4624 priv = dbe->priv;
4625 return priv->scanning_status;
4628 static inline gint
4629 sdb_engine_walk_down_scope_path (SymbolDBEngine *dbe, const GPtrArray* scope_path)
4631 SymbolDBEnginePriv *priv;
4632 gint final_definition_id;
4633 gint scope_path_len;
4634 gint i;
4635 gchar *query_str;
4636 GdaCommand *command;
4637 GdaDataModel *data;
4639 g_return_val_if_fail (dbe != NULL, FALSE);
4640 priv = dbe->priv;
4642 scope_path_len = scope_path->len;
4644 /* we'll return if the length is even or minor than 3 */
4645 if (scope_path_len < 3 || scope_path_len % 2 == 0)
4647 g_warning ("bad scope_path.");
4648 return -1;
4651 final_definition_id = 0;
4652 for (i=0; i < scope_path_len -1; i = i + 2)
4654 const GValue *value;
4655 DEBUG_PRINT ("loop final_definition_id %d", final_definition_id);
4657 query_str = g_strdup_printf ("SELECT scope_definition_id FROM symbol "
4658 "WHERE scope_id = '%d' AND scope_definition_id = ("
4659 "SELECT scope.scope_id FROM scope "
4660 "INNER JOIN sym_type ON scope.type_id = sym_type.type_id "
4661 "WHERE sym_type.type = '%s' "
4662 "AND scope.scope = '%s'"
4663 ")", final_definition_id, g_ptr_array_index (scope_path, i),
4664 g_ptr_array_index (scope_path, i + 1));
4666 DEBUG_PRINT ("walk down query is %s", query_str);
4667 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
4668 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
4670 if ( (data = gda_connection_execute_select_command (priv->db_connection,
4671 command, NULL, NULL)) == NULL ||
4672 gda_data_model_get_n_rows (data) <= 0 )
4674 gda_command_free (command);
4675 g_free (query_str);
4676 return -1;
4679 gda_command_free (command);
4680 g_free (query_str);
4682 value = gda_data_model_get_value_at (data, 0, 0);
4683 if (G_VALUE_HOLDS (value, G_TYPE_INT))
4685 final_definition_id = g_value_get_int (value);
4686 g_object_unref (data);
4688 else
4690 /* something went wrong. Our symbol cannot be retrieved coz of a
4691 * bad scope path.
4693 final_definition_id = -1;
4694 break;
4698 return final_definition_id;
4701 /* Returns an iterator to the data retrieved from database.
4702 * The iterator, if not null, will contain a list of parent classes for the given
4703 * symbol name.
4704 * namespace_name can be NULL.
4706 SymbolDBEngineIterator *
4707 symbol_db_engine_get_class_parents (SymbolDBEngine *dbe, gchar *klass_name,
4708 const GPtrArray *scope_path)
4710 SymbolDBEnginePriv *priv;
4711 gchar *query_str;
4712 GdaCommand *command;
4713 GdaDataModel *data;
4714 gint final_definition_id;
4716 g_return_val_if_fail (dbe != NULL, FALSE);
4717 priv = dbe->priv;
4719 final_definition_id = -1;
4720 if (scope_path != NULL)
4721 final_definition_id = sdb_engine_walk_down_scope_path (dbe, scope_path);
4723 /* FIXME: as always prepared queries of this complexity gives
4724 GDA_QUERY_TYPE_NON_PARSED_SQL error. */
4725 if (final_definition_id > 0)
4727 query_str = g_strdup_printf("SELECT symbol.symbol_id, symbol.name FROM heritage "
4728 "JOIN symbol ON heritage.symbol_id_base = symbol.symbol_id "
4729 "WHERE symbol_id_derived = ("
4730 "SELECT symbol_id FROM symbol "
4731 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id "
4732 "WHERE symbol.name = '%s' "
4733 "AND sym_kind.kind_name = 'class' "
4734 "AND symbol.scope_id = '%d'"
4735 ")", klass_name, final_definition_id);
4737 else
4739 query_str = g_strdup_printf("SELECT symbol.symbol_id, symbol.name FROM heritage "
4740 "JOIN symbol ON heritage.symbol_id_base = symbol.symbol_id "
4741 "WHERE symbol_id_derived = ("
4742 "SELECT symbol_id FROM symbol "
4743 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id "
4744 "WHERE symbol.name = '%s' "
4745 "AND sym_kind.kind_name = 'class' "
4746 ")", klass_name);
4749 DEBUG_PRINT ("get parents query: %s", query_str);
4750 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
4751 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
4753 if ( (data = gda_connection_execute_select_command (priv->db_connection,
4754 command, NULL, NULL)) == NULL ||
4755 gda_data_model_get_n_rows (data) <= 0 )
4757 gda_command_free (command);
4758 g_free (query_str);
4759 return NULL;
4762 gda_command_free (command);
4763 g_free (query_str);
4765 return (SymbolDBEngineIterator *)symbol_db_engine_iterator_new (data);
4768 static inline void
4769 sdb_engine_prepare_symbol_info_sql (SymbolDBEngine *dbe, GString *info_data,
4770 GString *join_data, gint sym_info)
4772 if (sym_info & SYMINFO_FILE_PATH ||
4773 sym_info & SYMINFO_LANGUAGE ||
4774 sym_info & SYMINFO_PROJECT_NAME ||
4775 sym_info & SYMINFO_FILE_IGNORE ||
4776 sym_info & SYMINFO_FILE_INCLUDE)
4778 info_data = g_string_append (info_data, ",file.file_path ");
4779 join_data = g_string_append (join_data, "LEFT JOIN file ON "
4780 "symbol.file_defined_id = file.file_id ");
4783 if (sym_info & SYMINFO_LANGUAGE)
4785 info_data = g_string_append (info_data, ",language.language_name ");
4786 join_data = g_string_append (join_data, "LEFT JOIN language ON "
4787 "file.lang_id = language.language_id ");
4790 if (sym_info & SYMINFO_IMPLEMENTATION)
4792 info_data = g_string_append (info_data, ",sym_implementation.implementation_name ");
4793 join_data = g_string_append (join_data, "LEFT JOIN sym_implementation ON "
4794 "symbol.implementation_kind_id = sym_implementation.sym_impl_id ");
4797 if (sym_info & SYMINFO_ACCESS)
4799 info_data = g_string_append (info_data, ",sym_access.access_name ");
4800 join_data = g_string_append (join_data, "LEFT JOIN sym_access ON "
4801 "symbol.access_kind_id = sym_access.access_kind_id ");
4804 if (sym_info & SYMINFO_KIND)
4806 info_data = g_string_append (info_data, ",sym_kind.kind_name ");
4807 join_data = g_string_append (join_data, "LEFT JOIN sym_kind ON "
4808 "symbol.kind_id = sym_kind.sym_kind_id ");
4811 if (sym_info & SYMINFO_TYPE || sym_info & SYMINFO_TYPE_NAME)
4813 info_data = g_string_append (info_data, ",sym_type.type,"
4814 "sym_type.type_name ");
4815 join_data = g_string_append (join_data, "LEFT JOIN sym_type ON "
4816 "symbol.type_id = sym_type.type_id ");
4819 if (sym_info & SYMINFO_PROJECT_NAME ||
4820 sym_info & SYMINFO_FILE_IGNORE ||
4821 sym_info & SYMINFO_FILE_INCLUDE)
4823 info_data = g_string_append (info_data, ",project.project_name ");
4824 join_data = g_string_append (join_data, "LEFT JOIN project ON "
4825 "file.prj_id = project.project_id ");
4828 if (sym_info & SYMINFO_FILE_IGNORE)
4830 info_data = g_string_append (info_data, ",file_ignore.type AS file_ignore_type ");
4831 join_data = g_string_append (join_data, "LEFT JOIN ext_ignore ON "
4832 "ext_ignore.prj_id = project.project_id "
4833 "LEFT JOIN file_ignore ON "
4834 "ext_ignore.file_ign_id = file_ignore.file_ignore_id ");
4837 if (sym_info & SYMINFO_FILE_INCLUDE)
4839 info_data = g_string_append (info_data, ",file_include.type AS file_include_type");
4840 join_data = g_string_append (join_data, "LEFT JOIN ext_ignore ON "
4841 "ext_iclude.prj_id = project.project_id "
4842 "LEFT JOIN file_include ON "
4843 "ext_include.file_incl_id = file_include.file_include_id ");
4846 /* TODO, or better.. TAKE A DECISION
4847 if (sym_info & SYMINFO_WORKSPACE_NAME)
4849 info_data = g_string_append (info_data, ",sym_access.access_name ");
4850 join_data = g_string_append (info_data, "LEFT JOIN sym_kind ON "
4851 "symbol.kind_id = sym_kind.sym_kind_id ");
4857 * kind can be NULL. In that case we'll return all the kinds of symbols found
4858 * at root level [global level].
4860 SymbolDBEngineIterator *
4861 symbol_db_engine_get_global_members (SymbolDBEngine *dbe,
4862 const gchar *kind, gint sym_info)
4864 SymbolDBEnginePriv *priv;
4865 GdaCommand *command;
4866 GdaDataModel *data;
4867 GString *info_data;
4868 GString *join_data;
4869 gchar *query_str;
4870 const gchar *real_kind;
4872 g_return_val_if_fail (dbe != NULL, NULL);
4873 priv = dbe->priv;
4875 /* check for an already flagged sym_info with KIND. SYMINFO_KIND on sym_info
4876 * is already contained into the default query infos.
4878 sym_info = sym_info & ~SYMINFO_KIND;
4880 /* info_data contains the stuff after SELECT and befor FROM */
4881 info_data = g_string_new ("");
4883 /* join_data contains the optionals joins to do to retrieve new data on other
4884 * tables.
4886 join_data = g_string_new ("");
4888 /* fill info_data and join data with optional sql */
4889 sdb_engine_prepare_symbol_info_sql (dbe, info_data, join_data, sym_info);
4891 if (kind == NULL)
4893 query_str = g_strdup_printf ("SELECT symbol.symbol_id, "
4894 "symbol.name, symbol.file_position, symbol.is_file_scope, "
4895 "symbol.signature, sym_kind.kind_name %s FROM symbol "
4896 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id %s "
4897 "WHERE scope_id <= 0", info_data->str, join_data->str);
4899 else
4901 query_str = g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
4902 "symbol.file_position, "
4903 "symbol.is_file_scope, symbol.signature %s FROM symbol "
4904 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id %s "
4905 "WHERE scope_id <= 0 "
4906 "AND sym_kind.kind_name = '%s'", info_data->str, join_data->str,
4907 kind);
4910 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
4911 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
4913 /* DEBUG_PRINT ("query is %s", query_str);*/
4914 if ( (data = gda_connection_execute_select_command (priv->db_connection,
4915 command, NULL, NULL)) == NULL ||
4916 gda_data_model_get_n_rows (data) <= 0 )
4918 gda_command_free (command);
4919 g_free (query_str);
4920 g_string_free (info_data, FALSE);
4921 g_string_free (join_data, FALSE);
4922 return NULL;
4925 gda_command_free (command);
4926 g_free (query_str);
4927 g_string_free (info_data, FALSE);
4928 g_string_free (join_data, FALSE);
4930 return (SymbolDBEngineIterator *)symbol_db_engine_iterator_new (data);
4936 * Sometimes it's useful going to query just with ids [and so integers] to have
4937 * a little speed improvement.
4939 SymbolDBEngineIterator *
4940 symbol_db_engine_get_scope_members_by_symbol_id (SymbolDBEngine *dbe,
4941 gint scope_parent_symbol_id, gint sym_info)
4944 select b.* from symbol a, symbol b where a.symbol_id = 348 and
4945 b.scope_id = a.scope_definition_id;
4947 SymbolDBEnginePriv *priv;
4948 gchar *query_str;
4949 GdaCommand *command;
4950 GdaDataModel *data;
4951 gint scope_path_len;
4952 gint i;
4953 gint final_definition_id;
4954 GString *info_data;
4955 GString *join_data;
4957 g_return_val_if_fail (dbe != NULL, NULL);
4958 priv = dbe->priv;
4960 if (scope_parent_symbol_id <= 0)
4961 return NULL;
4963 /* info_data contains the stuff after SELECT and befor FROM */
4964 info_data = g_string_new ("");
4966 /* join_data contains the optionals joins to do to retrieve new data on other
4967 * tables.
4969 join_data = g_string_new ("");
4971 /* fill info_data and join data with optional sql */
4972 sdb_engine_prepare_symbol_info_sql (dbe, info_data, join_data, sym_info);
4974 /* ok, beware that we use an 'alias hack' to accomplish compatibility with
4975 * sdb_engine_prepare_symbol_info_sql () function. In particular we called
4976 * the first joining table 'a', the second one 'symbol', where is the info we
4977 * want
4979 query_str = g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
4980 "symbol.file_position, "
4981 "symbol.is_file_scope, symbol.signature %s FROM symbol a, symbol symbol "
4982 "%s WHERE a.symbol_id = '%d' AND symbol.scope_id = a.scope_definition_id "
4983 "AND symbol.scope_id > 0", info_data->str, join_data->str,
4984 scope_parent_symbol_id);
4986 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
4987 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
4988 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
4990 if ( (data = gda_connection_execute_select_command (priv->db_connection,
4991 command, NULL, NULL)) == NULL ||
4992 gda_data_model_get_n_rows (data) <= 0 )
4994 gda_command_free (command);
4995 g_free (query_str);
4996 return NULL;
4999 gda_command_free (command);
5000 g_free (query_str);
5001 g_string_free (info_data, FALSE);
5002 g_string_free (join_data, FALSE);
5004 return (SymbolDBEngineIterator *)symbol_db_engine_iterator_new (data);
5007 /* scope_path cannot be NULL.
5008 * scope_path will be something like "scope1_kind", "scope1_name", "scope2_kind",
5009 * "scope2_name", NULL
5011 SymbolDBEngineIterator *
5012 symbol_db_engine_get_scope_members (SymbolDBEngine *dbe,
5013 const GPtrArray* scope_path, gint sym_info)
5016 simple scope
5018 select * from symbol where scope_id = (
5019 select scope.scope_id from scope
5020 inner join sym_type on scope.type_id = sym_type.type_id
5021 where sym_type.type = 'class'
5022 and scope.scope = 'MyClass'
5025 select * from symbol where scope_id = (
5026 select scope.scope_id from scope
5027 inner join sym_type on scope.type_id = sym_type.type_id
5028 where sym_type.type = 'struct'
5029 and scope.scope = '_faa_1');
5032 es. scope_path = First, namespace, Second, namespace, NULL,
5033 symbol_name = Second_1_class
5035 SymbolDBEnginePriv *priv;
5036 gchar *query_str;
5037 GdaCommand *command;
5038 GdaDataModel *data;
5039 gint scope_path_len;
5040 gint i;
5041 gint final_definition_id;
5042 GString *info_data;
5043 GString *join_data;
5045 g_return_val_if_fail (dbe != NULL, NULL);
5046 priv = dbe->priv;
5048 final_definition_id = sdb_engine_walk_down_scope_path (dbe, scope_path);
5050 if (final_definition_id <= 0)
5052 return NULL;
5055 /* info_data contains the stuff after SELECT and befor FROM */
5056 info_data = g_string_new ("");
5058 /* join_data contains the optionals joins to do to retrieve new data on other
5059 * tables.
5061 join_data = g_string_new ("");
5063 /* fill info_data and join data with optional sql */
5064 sdb_engine_prepare_symbol_info_sql (dbe, info_data, join_data, sym_info);
5066 query_str = g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5067 "symbol.file_position, "
5068 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5069 "%s WHERE scope_id = '%d'", info_data->str, join_data->str,
5070 final_definition_id);
5072 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
5073 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
5074 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
5076 if ( (data = gda_connection_execute_select_command (priv->db_connection,
5077 command, NULL, NULL)) == NULL ||
5078 gda_data_model_get_n_rows (data) <= 0 )
5080 gda_command_free (command);
5081 g_free (query_str);
5082 return NULL;
5085 gda_command_free (command);
5086 g_free (query_str);
5087 g_string_free (info_data, FALSE);
5088 g_string_free (join_data, FALSE);
5090 return (SymbolDBEngineIterator *)symbol_db_engine_iterator_new (data);
5093 /* Returns an iterator to the data retrieved from database.
5094 * It will be possible to get the scope specified by the line of the file.
5096 SymbolDBEngineIterator *
5097 symbol_db_engine_get_current_scope (SymbolDBEngine *dbe, const gchar* filename,
5098 gulong line)
5100 SymbolDBEnginePriv *priv;
5101 gchar *file_escaped;
5102 gchar *query_str;
5103 GdaCommand *command;
5104 GdaDataModel *data;
5106 g_return_val_if_fail (dbe != NULL, NULL);
5107 priv = dbe->priv;
5110 file_escaped = g_strescape (filename, NULL);
5112 /* WARNING: probably there can be some problems with escaping file names here.
5113 * They should come already escaped as from project db.
5115 query_str = g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5116 "symbol.file_position, "
5117 "symbol.is_file_scope, symbol.signature, MIN('%d' - symbol.file_position) "
5118 "FROM symbol "
5119 "JOIN file ON file_defined_id = file_id "
5120 "WHERE file.file_path = \"%s\" "
5121 "AND '%d' - symbol.file_position >= 0", line, file_escaped, line);
5123 DEBUG_PRINT ("current_scope query is %s", query_str);
5125 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
5126 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
5128 if ( (data = gda_connection_execute_select_command (priv->db_connection,
5129 command, NULL, NULL)) == NULL ||
5130 gda_data_model_get_n_rows (data) <= 0 )
5132 gda_command_free (command);
5133 g_free (query_str);
5134 g_free (file_escaped);
5135 return NULL;
5138 gda_command_free (command);
5139 g_free (query_str);
5140 g_free (file_escaped);
5141 return (SymbolDBEngineIterator *)symbol_db_engine_iterator_new (data);
5145 /* filepath: full local file path, e.g. /home/user/foo/file.c
5147 SymbolDBEngineIterator *
5148 symbol_db_engine_get_file_symbols (SymbolDBEngine *dbe,
5149 const gchar *file_path, gint sym_info)
5151 SymbolDBEnginePriv *priv;
5152 gchar *query_str;
5153 GdaCommand *command;
5154 GdaDataModel *data;
5155 gint i;
5156 gint final_definition_id;
5157 GString *info_data;
5158 GString *join_data;
5160 g_return_val_if_fail (dbe != NULL, NULL);
5161 g_return_val_if_fail (file_path != NULL, NULL);
5162 priv = dbe->priv;
5164 g_return_val_if_fail (priv->data_source != NULL, NULL);
5166 /* check for an already flagged sym_info with FILE_PATH. SYMINFO_FILE_PATH on
5167 * sym_info is already contained into the default query infos.
5169 sym_info = sym_info & ~SYMINFO_FILE_PATH;
5171 /* info_data contains the stuff after SELECT and befor FROM */
5172 info_data = g_string_new ("");
5174 /* join_data contains the optionals joins to do to retrieve new data on other
5175 * tables.
5177 join_data = g_string_new ("");
5179 /* fill info_data and join data with optional sql */
5180 sdb_engine_prepare_symbol_info_sql (dbe, info_data, join_data, sym_info);
5182 /* rember to do a file_path + strlen(priv->data_source): a project relative
5183 * file path
5185 query_str = g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5186 "symbol.file_position, "
5187 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5188 "JOIN file ON symbol.file_defined_id = file.file_id "
5189 "%s WHERE file.file_path = \"%s\"", info_data->str, join_data->str,
5190 file_path + strlen(priv->data_source));
5192 DEBUG_PRINT ("DYNAMIC query [file symbols] is %s", query_str);
5193 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
5194 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
5196 if ( (data = gda_connection_execute_select_command (priv->db_connection,
5197 command, NULL, NULL)) == NULL ||
5198 gda_data_model_get_n_rows (data) <= 0 )
5200 gda_command_free (command);
5201 g_free (query_str);
5202 return NULL;
5205 gda_command_free (command);
5206 g_free (query_str);
5207 g_string_free (info_data, FALSE);
5208 g_string_free (join_data, FALSE);
5210 return (SymbolDBEngineIterator *)symbol_db_engine_iterator_new (data);
5214 SymbolDBEngineIterator *
5215 symbol_db_engine_get_symbol_info_by_id (SymbolDBEngine *dbe,
5216 gint sym_id, gint sym_info)
5218 SymbolDBEnginePriv *priv;
5219 gchar *query_str;
5220 GdaCommand *command;
5221 GdaDataModel *data;
5222 GString *info_data;
5223 GString *join_data;
5225 g_return_val_if_fail (dbe != NULL, NULL);
5226 priv = dbe->priv;
5228 /* info_data contains the stuff after SELECT and befor FROM */
5229 info_data = g_string_new ("");
5231 /* join_data contains the optionals joins to do to retrieve new data on other
5232 * tables.
5234 join_data = g_string_new ("");
5236 /* fill info_data and join data with optional sql */
5237 sdb_engine_prepare_symbol_info_sql (dbe, info_data, join_data, sym_info);
5239 query_str = g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5240 "symbol.file_position, "
5241 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5242 "%s WHERE symbol.symbol_id = %d", info_data->str, join_data->str,
5243 sym_id);
5245 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
5246 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
5247 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
5249 if ( (data = gda_connection_execute_select_command (priv->db_connection,
5250 command, NULL, NULL)) == NULL ||
5251 gda_data_model_get_n_rows (data) <= 0 )
5253 gda_command_free (command);
5254 g_free (query_str);
5255 return NULL;
5258 gda_command_free (command);
5259 g_free (query_str);
5260 g_string_free (info_data, FALSE);
5261 g_string_free (join_data, FALSE);
5263 return (SymbolDBEngineIterator *)symbol_db_engine_iterator_new (data);
5267 /* user must free the returned value */
5268 gchar*
5269 symbol_db_engine_get_full_local_path (SymbolDBEngine *dbe, const gchar* file)
5271 SymbolDBEnginePriv *priv;
5272 gchar *full_path;
5274 g_return_val_if_fail (dbe != NULL, NULL);
5276 priv = dbe->priv;
5277 /* DEBUG_PRINT ("joining %s with %s", priv->data_source, file);*/
5278 full_path = g_strdup_printf ("%s%s", priv->data_source, file);
5279 return full_path;
5283 SymbolDBEngineIterator *
5284 symbol_db_engine_find_symbol_by_name_pattern (SymbolDBEngine *dbe,
5285 const gchar *name, gint sym_info)
5287 SymbolDBEnginePriv *priv;
5288 gchar *query_str;
5289 GdaCommand *command;
5290 GdaDataModel *data;
5291 GString *info_data;
5292 GString *join_data;
5294 g_return_val_if_fail (dbe != NULL, NULL);
5295 priv = dbe->priv;
5297 /* info_data contains the stuff after SELECT and befor FROM */
5298 info_data = g_string_new ("");
5300 /* join_data contains the optionals joins to do to retrieve new data on other
5301 * tables.
5303 join_data = g_string_new ("");
5305 /* fill info_data and join data with optional sql */
5306 sdb_engine_prepare_symbol_info_sql (dbe, info_data, join_data, sym_info);
5308 query_str = g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5309 "symbol.file_position, "
5310 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5311 "%s WHERE symbol.name LIKE \"%s%%\"", info_data->str, join_data->str,
5312 name);
5314 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
5315 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
5316 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
5318 if ( (data = gda_connection_execute_select_command (priv->db_connection,
5319 command, NULL, NULL)) == NULL ||
5320 gda_data_model_get_n_rows (data) <= 0 )
5322 gda_command_free (command);
5323 g_free (query_str);
5324 return NULL;
5327 gda_command_free (command);
5328 g_free (query_str);
5329 g_string_free (info_data, FALSE);
5330 g_string_free (join_data, FALSE);
5332 return (SymbolDBEngineIterator *)symbol_db_engine_iterator_new (data);
5335 /* No iterator for now. We need the quickest query possible. */
5336 gint
5337 symbol_db_engine_get_parent_scope_id_by_symbol_id (SymbolDBEngine *dbe,
5338 gint scoped_symbol_id)
5341 select * from symbol where scope_definition_id = (
5342 select scope_id from symbol where symbol_id = 26
5346 /* again we're without prepared queries support from libgda... hope
5347 * you guys implement that asap..!
5349 SymbolDBEnginePriv *priv;
5350 gchar *query_str;
5351 GdaCommand *command;
5352 GdaDataModel *data;
5353 const GValue* value;
5355 g_return_val_if_fail (dbe != NULL, -1);
5356 priv = dbe->priv;
5358 query_str = g_strdup_printf ("SELECT symbol.symbol_id FROM symbol "
5359 "WHERE symbol.scope_definition_id = ( "
5360 "SELECT symbol.scope_id FROM symbol WHERE symbol.symbol_id = '%d')",
5361 scoped_symbol_id);
5363 DEBUG_PRINT ("symbol_db_engine_get_parent_scope_id_by_symbol_id() query is %s",
5364 query_str);
5365 command = gda_command_new (query_str, GDA_COMMAND_TYPE_SQL,
5366 GDA_COMMAND_OPTION_STOP_ON_ERRORS);
5368 if ( (data = gda_connection_execute_select_command (priv->db_connection,
5369 command, NULL, NULL)) == NULL ||
5370 gda_data_model_get_n_rows (data) <= 0 )
5372 gda_command_free (command);
5373 g_free (query_str);
5374 DEBUG_PRINT ("BAILING OUT");
5375 return -1;
5378 gda_command_free (command);
5379 g_free (query_str);
5381 value = gda_data_model_get_value_at (data, 0, 0);
5382 gint res = value != NULL && G_VALUE_HOLDS_INT (value)
5383 ? g_value_get_int (value) : -1;
5384 g_object_unref (data);
5386 return res;