1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) Massimo Cora' 2007 <maxcvs@email.it>
6 * anjuta is free software.
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)
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.
29 ------------------------
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";
46 select * from symbol where scope_id = ;
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
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"
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
71 = get the *derived 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'
106 #include <sys/types.h>
107 #include <sys/mman.h>
109 #include <fcntl.h> /* For O_* constants */
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"
134 DONT_FAKE_UPDATE_SYMS
,
135 END_UPDATE_GROUP_SYMS
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
,
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
,
180 typedef struct _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
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'))",
204 PREP_QUERY_GET_WORKSPACE_ID_BY_UNIQUE_NAME
,
205 "SELECT workspace_id FROM workspace WHERE workspace_name = ## /* name:'wsname' "
206 "type:gchararray */",
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'))",
218 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME
,
219 "SELECT project_id FROM project WHERE project_name = ## /* name:'prjname' "
220 "type:gchararray */",
224 PREP_QUERY_UPDATE_PROJECT_ANALIZE_TIME
,
225 "UPDATE project SET analize_time = datetime('now', 'localtime') WHERE "
226 "project_name = ## /* name:'prjname' type:gchararray */",
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'))",
239 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME
,
240 "SELECT file_id FROM file WHERE file_path = ## /* name:'filepath' "
241 "type:gchararray */",
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 */)",
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 * /",
260 PREP_QUERY_UPDATE_FILE_ANALIZE_TIME
,
261 "UPDATE file SET analize_time = datetime('now', 'localtime') WHERE "
262 "file_path = ## /* name:'filepath' type:gchararray */",
266 PREP_QUERY_LANGUAGE_NEW
,
267 "INSERT INTO language (language_name) VALUES (## /* name:'langname' "
268 "type:gchararray */)",
272 PREP_QUERY_GET_LANGUAGE_ID_BY_UNIQUE_NAME
,
273 "SELECT language_id FROM language WHERE language_name = ## /* name:'langname' "
274 "type:gchararray */",
279 PREP_QUERY_SYM_TYPE_NEW
,
280 "INSERT INTO sym_type (type, type_name) VALUES (## /* name:'type' "
281 "type:gchararray */, ## /* name:'typename' type:gchararray */)",
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 */",
293 PREP_QUERY_SYM_KIND_NEW
,
294 "INSERT INTO sym_kind (kind_name) VALUES(## /* name:'kindname' "
295 "type:gchararray */)",
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 */",
304 /* -- sym access -- */
306 PREP_QUERY_SYM_ACCESS_NEW
,
307 "INSERT INTO sym_access (access_name) VALUES(## /* name:'accesskind' "
308 "type:gchararray */)",
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 */",
317 /* -- sym implementation -- */
319 PREP_QUERY_SYM_IMPLEMENTATION_NEW
,
320 "INSERT INTO sym_implementation (implementation_name) VALUES(## /* name:'implekind' "
321 "type:gchararray */)",
325 PREP_QUERY_GET_SYM_IMPLEMENTATION_BY_UNIQUE_NAME
,
326 "SELECT sym_impl_id FROM sym_implementation WHERE kind = ## /* "
327 "name:'implekind' type:gchararray */",
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 */)",
339 PREP_QUERY_SCOPE_NEW
,
340 "INSERT INTO scope (scope, type_id) VALUES(## /* name:'scope' "
341 "type:gchararray */, ## /* name:'typeid' type:gint */)",
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 */",
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 */)",
364 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE
,
365 "SELECT * FROM __tmp_heritage_scope",
369 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE_WITH_INHERITS
,
370 "SELECT * FROM __tmp_heritage_scope WHERE field_inherits != ''",
374 PREP_QUERY_TMP_HERITAGE_DELETE_ALL
,
375 "DELETE FROM __tmp_heritage_scope",
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 */)",
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 */",
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 */",
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'",
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 */",
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 */",
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:"
444 /* -- tmp_removed -- */
446 PREP_QUERY_GET_REMOVED_IDS
,
447 "SELECT symbol_removed_id FROM __tmp_removed",
451 PREP_QUERY_TMP_REMOVED_DELETE_ALL
,
452 "DELETE FROM __tmp_removed",
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
,
473 static unsigned int signals
[LAST_SIGNAL
] = { 0 };
476 struct _SymbolDBEnginePriv
478 GdaConnection
*db_connection
;
479 GdaClient
*gda_client
;
485 GAsyncQueue
*scan_queue
;
487 GAsyncQueue
*updated_symbols_id
;
488 GAsyncQueue
*inserted_symbols_id
;
490 gchar
*shared_mem_str
;
491 FILE *shared_mem_file
;
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
);
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.
512 sdb_engine_execute_non_select_sql (SymbolDBEngine
* dbe
, const gchar
* buffer
)
514 SymbolDBEnginePriv
*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.
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
);
537 if (priv
->project_name
== NULL
)
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
)
553 SymbolDBEnginePriv
*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 */
575 gda_query_new_from_sql (priv
->dict
, node
->query_str
, NULL
);
582 sdb_engine_get_last_insert_id (SymbolDBEngine
* dbe
)
587 SymbolDBEnginePriv
*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
,
603 || gda_data_model_get_n_rows (data
) <= 0)
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
);
614 g_object_unref (data
);
619 * Clear the static cached queries data. You should call this function when closing/
620 * destroying SymbolDBEngine object.
621 * priv->dict is also destroyed.
624 sdb_engine_free_cached_queries (SymbolDBEngine
* dbe
)
628 SymbolDBEnginePriv
*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
);
643 /* destroys also dict */
644 g_object_unref (priv
->dict
);
648 sdb_engine_disconnect_from_db (SymbolDBEngine
* dbe
)
650 SymbolDBEnginePriv
*priv
;
652 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
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
;
671 g_free (priv
->dsn_name
);
672 priv
->dsn_name
= NULL
;
677 g_object_unref (priv
->dict
);
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.
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
)
698 tagFileInfo tag_file_info
;
701 SymbolDBEnginePriv
*priv
;
703 g_return_if_fail (dbe
!= NULL
);
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
,
729 gda_connection_commit_transaction (priv
->db_connection
, "fixme", NULL
);
733 sdb_engine_ctags_output_callback_1 (AnjutaLauncher
* launcher
,
734 AnjutaLauncherOutputType output_type
,
735 const gchar
* chars
, gpointer user_data
)
739 gint remaining_chars
;
742 SymbolDBEnginePriv
*priv
;
745 g_return_if_fail (user_data
!= NULL
);
746 g_return_if_fail (chars
!= NULL
);
748 dbe
= (SymbolDBEngine
*)user_data
;
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
);
767 if (marker_ptr
!= NULL
)
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
,
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
)
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)
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);
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
);
855 /* found out a new marker */
856 marker_ptr
= strstr (marker_ptr
+ len_marker
, CTAGS_MARKER
);
857 } while (remaining_chars
+ len_marker
< len_chars
);
861 DEBUG_PRINT ("no len_chars > len_marker");
866 on_scan_files_end_1 (AnjutaLauncher
* launcher
, int child_pid
,
867 int exit_status
, gulong time_taken_in_seconds
,
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
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 */
891 sdb_engine_scan_files_1 (SymbolDBEngine
* dbe
, const GPtrArray
* files_list
,
892 const GPtrArray
*real_files_list
, gboolean symbols_update
)
894 SymbolDBEnginePriv
*priv
;
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)
903 /* start process in server mode */
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");
912 /* if ctags_launcher isn't initialized, then do it now. */
913 if (priv
->ctags_launcher
== NULL
)
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
"'",
927 anjuta_launcher_execute (priv
->ctags_launcher
,
928 exe_string
, sdb_engine_ctags_output_callback_1
,
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)
945 temp_file
= g_strdup_printf ("/anjuta-%d_%ld.tags", getpid (),
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
);
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
);
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
990 if (real_files_list
!= NULL
)
992 g_async_queue_push (priv
->scan_queue
,
994 g_ptr_array_index (real_files_list
, i
)));
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
;
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
;
1048 sdb_engine_finalize (GObject
* object
)
1050 SymbolDBEngine
*dbe
;
1051 SymbolDBEnginePriv
*priv
;
1053 dbe
= SYMBOL_DB_ENGINE (object
);
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
);
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
;
1114 = g_signal_new ("scan-end",
1115 G_OBJECT_CLASS_TYPE (object_class
),
1117 G_STRUCT_OFFSET (SymbolDBEngineClass
, scan_end
),
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
),
1125 G_STRUCT_OFFSET (SymbolDBEngineClass
, symbol_inserted
),
1127 g_cclosure_marshal_VOID__INT
, G_TYPE_NONE
,
1131 signals
[SYMBOL_UPDATED
]
1132 = g_signal_new ("symbol-updated",
1133 G_OBJECT_CLASS_TYPE (object_class
),
1135 G_STRUCT_OFFSET (SymbolDBEngineClass
, symbol_updated
),
1137 g_cclosure_marshal_VOID__INT
, G_TYPE_NONE
,
1141 signals
[SYMBOL_REMOVED
]
1142 = g_signal_new ("symbol-removed",
1143 G_OBJECT_CLASS_TYPE (object_class
),
1145 G_STRUCT_OFFSET (SymbolDBEngineClass
, symbol_removed
),
1147 g_cclosure_marshal_VOID__INT
, G_TYPE_NONE
,
1154 symbol_db_engine_get_type (void)
1156 static GType 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",
1181 symbol_db_engine_new (void)
1183 SymbolDBEngine
*sdbe
;
1185 sdbe
= g_object_new (SYMBOL_TYPE_DB_ENGINE
, NULL
);
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.
1195 sdb_engine_connect_to_db (SymbolDBEngine
* dbe
, const gchar
* data_source
)
1197 SymbolDBEnginePriv
*priv
;
1199 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
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.");
1212 /* create new client */
1213 priv
->gda_client
= gda_client_new ();
1215 /* establish a connection. If the sqlite file does not exist it will
1219 = gda_client_open_connection (priv
->gda_client
, data_source
,
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
);
1229 g_message ("connected to database %s", data_source
);
1235 * Creates required tables for the database to work.
1236 * @param tables_sql_file File containing sql code.
1239 sdb_engine_create_db_tables (SymbolDBEngine
* dbe
, gchar
* tables_sql_file
)
1242 GdaCommand
*command
;
1243 SymbolDBEnginePriv
*priv
;
1247 g_return_val_if_fail (tables_sql_file
!= NULL
, FALSE
);
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",
1260 g_message ("%s", err
->message
);
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
,
1268 gda_command_free (command
);
1274 * Check if the database already exists into the prj_directory
1277 symbol_db_engine_db_exists (SymbolDBEngine
* dbe
, gchar
* prj_directory
)
1279 SymbolDBEnginePriv
*priv
;
1281 g_return_val_if_fail (prj_directory
!= NULL
, FALSE
);
1285 /* check whether the db filename already exists.*/
1286 gchar
*tmp_file
= g_strdup_printf ("%s/%s.db", prj_directory
,
1289 if (g_file_test (tmp_file
, G_FILE_TEST_EXISTS
) == FALSE
)
1291 DEBUG_PRINT ("db %s does not exist", tmp_file
);
1297 DEBUG_PRINT ("db %s does exist", tmp_file
);
1302 * Open or create a new database at given directory.
1305 symbol_db_engine_open_db (SymbolDBEngine
* dbe
, gchar
* prj_directory
)
1307 SymbolDBEnginePriv
*priv
;
1308 /* Connection data */
1310 gboolean needs_tables_creation
= FALSE
;
1312 g_return_val_if_fail (prj_directory
!= NULL
, FALSE
);
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
,
1321 if (g_file_test (tmp_file
, G_FILE_TEST_EXISTS
) == FALSE
)
1323 needs_tables_creation
= TRUE
;
1328 priv
->data_source
= g_strdup (prj_directory
);
1329 dsn_name
= g_strdup_printf ("DB_DIR=%s;DB_NAME=%s", prj_directory
,
1332 if (gda_config_save_data_source (priv
->data_source
, "SQLite",
1333 dsn_name
, "Anjuta Project",
1334 "", "", FALSE
) == 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
);
1356 * @return -1 on error. Otherwise the id of table
1359 sdb_engine_get_table_id_by_unique_name (SymbolDBEngine
* dbe
, query_type qtype
,
1361 const GValue
* param_value
)
1363 const GdaQuery
*query
;
1364 GdaParameterList
*par_list
;
1365 GdaParameter
*param
;
1369 /* get prepared query */
1370 if ((query
= sdb_engine_get_query_by_id (dbe
, qtype
)) == NULL
)
1372 g_warning ("query is null");
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 "
1384 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1386 g_warning ("par_list is NULL!\n");
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 "
1397 gda_parameter_set_value (param
, param_value
);
1399 /* execute the query with parametes just set */
1401 G_OBJECT (gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
,
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]",
1411 g_object_unref (obj
);
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
);
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
1431 sdb_engine_get_table_id_by_unique_name2 (SymbolDBEngine
* dbe
, query_type qtype
,
1433 const GValue
* value1
,
1435 const GValue
* value2
)
1437 const GdaQuery
*query
;
1438 GdaParameterList
*par_list
;
1439 GdaParameter
*param
;
1444 /* get prepared query */
1445 if ((query
= sdb_engine_get_query_by_id (dbe
, qtype
)) == NULL
)
1447 g_warning ("query is null");
1451 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1452 == gda_query_get_query_type ((GdaQuery
*) query
))
1455 ("sdb_engine_get_table_id_by_unique_name2: non parsed sql error");
1459 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1461 g_warning ("par_list is NULL!\n");
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
);
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");
1483 gda_parameter_set_value (param
, value2
);
1485 /* execute the query with parametes just set */
1487 G_OBJECT (gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
,
1490 if (!GDA_IS_DATA_MODEL (obj
) ||
1491 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj
)) <= 0)
1495 g_object_unref (obj
);
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
);
1508 sdb_engine_get_table_id_by_unique_name3 (SymbolDBEngine
* dbe
, query_type qtype
,
1510 const GValue
* value1
,
1512 const GValue
* value2
,
1514 const GValue
* value3
)
1516 const GdaQuery
*query
;
1517 GdaParameterList
*par_list
;
1518 GdaParameter
*param
;
1523 /* get prepared query */
1524 if ((query
= sdb_engine_get_query_by_id (dbe
, qtype
)) == NULL
)
1526 g_warning ("query is null");
1530 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1531 == gda_query_get_query_type ((GdaQuery
*) query
))
1534 ("sdb_engine_get_table_id_by_unique_name2: non parsed sql error");
1538 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1540 g_warning ("par_list is NULL!\n");
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
);
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");
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");
1571 gda_parameter_set_value (param
, value3
);
1574 /* execute the query with parametes just set */
1576 G_OBJECT (gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
,
1579 if (!GDA_IS_DATA_MODEL (obj
) ||
1580 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj
)) <= 0)
1584 g_object_unref (obj
);
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
);
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,
1607 const GdaQuery
*query
;
1608 GdaParameterList
*par_list
;
1609 GdaParameter
*param
;
1611 SymbolDBEnginePriv
*priv
;
1615 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
1619 sdb_engine_get_query_by_id (dbe
, PREP_QUERY_WORKSPACE_NEW
)) == NULL
)
1621 g_warning ("query is null");
1625 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
1626 gda_query_get_query_type ((GdaQuery
*) query
))
1628 g_warning ("non parsed sql error");
1632 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1634 g_warning ("par_list is NULL!\n");
1638 if ((param
= gda_parameter_list_find_param (par_list
, "wsname")) == NULL
)
1640 g_warning ("param is NULL from pquery!\n");
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
);
1656 * Return the name of the opened project.
1657 * NULL on error. Returned string must be freed by caller.
1660 symbol_db_engine_get_opened_project_name (SymbolDBEngine
* dbe
)
1662 SymbolDBEnginePriv
*priv
;
1665 g_return_val_if_fail (dbe
!= NULL
, NULL
);
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.
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
;
1685 SymbolDBEnginePriv
*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
);
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
,
1706 gda_value_free (value
);
1710 gda_value_free (value
);
1712 /* open the project... */
1713 priv
->project_name
= g_strdup (project_name
);
1720 symbol_db_engine_close_project (SymbolDBEngine
*dbe
, gchar
* project_name
)
1722 SymbolDBEnginePriv
*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
1743 symbol_db_engine_add_new_project (SymbolDBEngine
* dbe
, gchar
* workspace
,
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),
1753 const GdaQuery
*query
;
1754 GdaParameterList
*par_list
;
1755 GdaParameter
*param
;
1757 gchar
*workspace_name
;
1759 SymbolDBEnginePriv
*priv
;
1761 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
1765 if (symbol_db_engine_is_project_opened (dbe
, project
) == TRUE
)
1767 g_warning ("You have an already opened project. Cannot continue.");
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");
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
,
1797 DEBUG_PRINT ("no workspace id");
1798 gda_value_free (value
);
1802 /* insert new project */
1804 sdb_engine_get_query_by_id (dbe
, PREP_QUERY_PROJECT_NEW
)) == NULL
)
1806 g_warning ("query is null");
1807 gda_value_free (value
);
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
);
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
);
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
);
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!");
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
);
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);
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
,
1878 /* insert a new entry on db */
1879 const GdaQuery
*query
;
1880 GdaParameterList
*par_list
;
1881 GdaParameter
*param
;
1884 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_LANGUAGE_NEW
))
1887 g_warning ("query is null");
1891 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
1892 gda_query_get_query_type ((GdaQuery
*) query
))
1894 g_warning ("non parsed sql error");
1899 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1901 g_warning ("par_list is NULL!\n");
1906 gda_parameter_list_find_param (par_list
, "langname")) == NULL
)
1908 g_warning ("param langname is NULL from pquery!");
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
);
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.
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),
1945 SymbolDBEnginePriv
*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
,
1962 g_warning ("no project with that name exists");
1963 gda_value_free (value
);
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
,
1980 /* insert a new entry on db */
1981 const GdaQuery
*query
;
1982 GdaParameterList
*par_list
;
1983 GdaParameter
*param
;
1986 language_id
= sdb_engine_add_new_language (dbe
, language
);
1988 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_FILE_NEW
))
1991 g_warning ("query is null");
1995 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
1996 gda_query_get_query_type ((GdaQuery
*) query
))
1998 g_warning ("non parsed sql error");
2003 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2005 g_warning ("par_list is NULL!\n");
2009 /* filepath parameter */
2011 gda_parameter_list_find_param (par_list
, "filepath")) == NULL
)
2013 g_warning ("param filepath is NULL from pquery!");
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!");
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 */
2035 gda_parameter_list_find_param (par_list
, "langid")) == NULL
)
2037 g_warning ("param langid is NULL from pquery!");
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
);
2055 symbol_db_engine_add_new_files (SymbolDBEngine
* dbe
, gchar
* project
,
2056 const GPtrArray
* files_path
, gchar
* language
,
2057 gboolean scan_symbols
)
2060 SymbolDBEnginePriv
*priv
;
2062 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
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
);
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
);
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
);
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.
2101 return sdb_engine_scan_files_1 (dbe
, files_path
, NULL
, FALSE
);
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)
2118 const gchar
*type_name
;
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
,
2139 const GdaQuery
*query
;
2140 GdaParameterList
*par_list
;
2141 GdaParameter
*param
;
2144 /* it does not exist. Create a new tuple. */
2145 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SYM_TYPE_NEW
))
2148 g_warning ("query is null");
2152 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2153 gda_query_get_query_type ((GdaQuery
*) query
))
2155 g_warning ("non parsed sql error");
2160 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2162 g_warning ("par_list is NULL!\n");
2166 /* type parameter */
2167 if ((param
= gda_parameter_list_find_param (par_list
, "type")) == NULL
)
2169 g_warning ("param type is NULL from pquery!");
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 */
2179 gda_parameter_list_find_param (par_list
, "typename")) == NULL
)
2181 g_warning ("param typename is NULL from pquery!");
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
);
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
;
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
)
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
,
2230 const GdaQuery
*query
;
2231 GdaParameterList
*par_list
;
2232 GdaParameter
*param
;
2235 /* not found. Go on with inserting */
2238 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SYM_KIND_NEW
))
2241 g_warning ("query is null");
2245 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2246 gda_query_get_query_type ((GdaQuery
*) query
))
2248 g_warning ("non parsed sql error");
2253 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2255 g_warning ("par_list is NULL!\n");
2259 /* kindname parameter */
2261 gda_parameter_list_find_param (par_list
, "kindname")) == NULL
)
2263 g_warning ("param kindname is NULL from pquery!");
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
);
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
;
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 */
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
,
2309 const GdaQuery
*query
;
2310 GdaParameterList
*par_list
;
2311 GdaParameter
*param
;
2314 /* not found. Go on with inserting */
2318 sdb_engine_get_query_by_id (dbe
,
2319 PREP_QUERY_SYM_ACCESS_NEW
)) == NULL
)
2321 g_warning ("query is null");
2325 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2326 gda_query_get_query_type ((GdaQuery
*) query
))
2328 g_warning ("non parsed sql error");
2333 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2335 g_warning ("par_list is NULL!\n");
2339 /* accesskind parameter */
2341 gda_parameter_list_find_param (par_list
, "accesskind")) == NULL
)
2343 g_warning ("param accesskind is NULL from pquery!");
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
);
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
;
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 */
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
,
2390 const GdaQuery
*query
;
2391 GdaParameterList
*par_list
;
2392 GdaParameter
*param
;
2395 /* not found. Go on with inserting */
2397 sdb_engine_get_query_by_id (dbe
,
2398 PREP_QUERY_SYM_IMPLEMENTATION_NEW
)) ==
2401 g_warning ("query is null");
2405 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2406 gda_query_get_query_type ((GdaQuery
*) query
))
2408 g_warning ("non parsed sql error");
2413 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2415 g_warning ("par_list is NULL!\n");
2419 /* implekind parameter */
2421 gda_parameter_list_find_param (par_list
, "implekind")) == NULL
)
2423 g_warning ("param implekind is NULL from pquery!");
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
);
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
;
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
))
2463 g_warning ("query is null");
2467 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2468 gda_query_get_query_type ((GdaQuery
*) query
))
2470 g_warning ("non parsed sql error");
2474 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2476 g_warning ("par_list is NULL!\n");
2480 /* symbase parameter */
2481 if ((param
= gda_parameter_list_find_param (par_list
, "symbase")) == NULL
)
2483 g_warning ("param symbase is NULL from pquery!");
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 */
2493 gda_parameter_list_find_param (par_list
, "symderived")) == NULL
)
2495 g_warning ("param symderived is NULL from pquery!");
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
);
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)
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)
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
,
2553 /* no type has been found. */
2554 gda_value_free (value1
);
2555 gda_value_free (value2
);
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
,
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
;
2581 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SCOPE_NEW
))
2584 g_warning ("query is null");
2588 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2589 gda_query_get_query_type ((GdaQuery
*) query
))
2591 g_warning ("non parsed sql error");
2596 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2598 g_warning ("par_list is NULL!\n");
2602 /* scope parameter */
2603 if ((param
= gda_parameter_list_find_param (par_list
, "scope")) == NULL
)
2605 g_warning ("param scope is NULL from pquery!");
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 */
2615 gda_parameter_list_find_param (par_list
, "typeid")) == NULL
)
2617 g_warning ("param typeid is NULL from pquery!");
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
);
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.
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
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
;
2667 const gchar
*field_inherits
, *field_struct
, *field_typeref
,
2668 *field_enum
, *field_union
, *field_class
, *field_namespace
;
2671 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2676 if ((field_inherits
= tagsField (tag_entry
, "inherits")) == NULL
)
2678 field_inherits
= "";
2683 if ((field_struct
= tagsField (tag_entry
, "struct")) == NULL
)
2690 if ((field_typeref
= tagsField (tag_entry
, "typeref")) == NULL
)
2697 if ((field_enum
= tagsField (tag_entry
, "enum")) == NULL
)
2704 if ((field_union
= tagsField (tag_entry
, "union")) == NULL
)
2711 if ((field_class
= tagsField (tag_entry
, "class")) == NULL
)
2718 if ((field_namespace
= tagsField (tag_entry
, "namespace")) == NULL
)
2720 field_namespace
= "";
2729 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_TMP_HERITAGE_NEW
))
2732 g_warning ("query is null");
2736 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2737 gda_query_get_query_type ((GdaQuery
*) query
))
2739 g_warning ("non parsed sql error");
2743 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2745 g_warning ("par_list is NULL!\n");
2749 /* symreferid parameter */
2751 gda_parameter_list_find_param (par_list
, "symreferid")) == NULL
)
2753 g_warning ("param symreferid is NULL from pquery!");
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!");
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!");
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!");
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!");
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!");
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!");
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 */
2829 gda_parameter_list_find_param (par_list
, "fnamespace")) == NULL
)
2831 g_warning ("param fnamespace is NULL from pquery!");
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
);
2849 sdb_engine_second_pass_update_scope_1 (SymbolDBEngine
* dbe
,
2850 GdaDataModel
* data
, gint data_row
,
2852 const GValue
* token_value
)
2855 GdaCommand
*command
;
2856 GValue
*value1
, *value2
, *value
;
2857 const GValue
*value_id2
;
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)
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]);
2895 g_strfreev (tmp_str_splitted
);
2899 g_strfreev (tmp_str_splitted
);
2902 * DEBUG_PRINT ("2nd pass scope: got %s %s (from %s)", token_name, object_name,
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
,
2918 if (free_token_name
)
2919 g_free (token_name
);
2921 gda_value_free (value1
);
2922 gda_value_free (value2
);
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",
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
))
2944 g_warning ("query is null");
2948 if (GDA_QUERY_TYPE_NON_PARSED_SQL
2949 == gda_query_get_query_type ((GdaQuery
*) query
))
2951 g_warning ("non parsed sql error");
2955 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2957 g_warning ("par_list is NULL!\n");
2961 /* scopeid parameter */
2962 if ((param
= gda_parameter_list_find_param (par_list
, "scopeid")) == NULL
)
2964 g_warning ("param scopeid is NULL from pquery!");
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!");
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
);
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.
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
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.
3014 for (i
= 0; i
< gda_data_model_get_n_rows (data
); i
++)
3019 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3023 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "class",
3028 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3032 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "struct",
3037 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3041 /* this is a "typedef", not a "typeref". */
3042 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "typedef",
3047 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3051 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "enum", value
);
3055 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3059 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "union",
3064 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3068 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "namespace",
3076 * @param data Must be filled with some values. It must have num_rows > 0
3077 * @note *CALL THIS AFTER second_pass_update_scope ()*
3080 sdb_engine_second_pass_update_heritage (SymbolDBEngine
* dbe
,
3081 GdaDataModel
* data
)
3084 SymbolDBEnginePriv
*priv
;
3086 g_return_if_fail (dbe
!= NULL
);
3090 for (i
= 0; i
< gda_data_model_get_n_rows (data
); i
++)
3092 const GValue
*value
;
3093 const gchar
*inherits
;
3095 gchar
**inherits_list
;
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
++)
3113 gchar
*namespace_name
;
3114 gint namespaces_length
;
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
3136 namespace_name
= g_strdup (namespaces
[namespaces_length
- 2]);
3137 klass_name
= g_strdup (namespaces
[namespaces_length
- 1]);
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
;
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)
3160 g_strdup (tmp_namespace_array
3161 [tmp_namespace_length
- 1]);
3163 namespace_name
= NULL
;
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
,
3183 derived_klass_id
= g_value_get_int (value
);
3187 derived_klass_id
= 0;
3190 /* ok, search for the symbol_id of the base class */
3191 if (namespace_name
== NULL
)
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
,
3204 gda_value_free (value1
);
3207 gda_value_free (value1
);
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
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,
3233 gda_value_free (value1);
3234 gda_value_free (value2);
3237 gda_value_free (value1);
3238 gda_value_free (value2);
3241 GdaCommand
*command
;
3242 GdaDataModel
*base_data
;
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
);
3256 gda_connection_execute_select_command (priv
->db_connection
,
3259 gda_data_model_get_n_rows (base_data
) <= 0 )
3261 gda_command_free (command
);
3264 if (base_data
!= NULL
)
3265 g_object_unref (base_data
);
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
);
3276 if (base_data
!= NULL
)
3277 g_object_unref (base_data
);
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
,
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
3297 * *CALL THIS FUNCTION ONLY AFTER HAVING PARSED ALL THE TAGS ONCE*
3301 sdb_engine_second_pass_do (SymbolDBEngine
* dbe
)
3304 const GdaQuery
*query1
, *query2
, *query3
;
3306 /* prepare for scope second scan */
3308 sdb_engine_get_query_by_id (dbe
,
3309 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE
))
3312 g_warning ("query is null");
3316 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3317 gda_query_get_query_type ((GdaQuery
*) query1
))
3319 g_warning ("non parsed sql error");
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)
3331 g_object_unref (obj
);
3336 sdb_engine_second_pass_update_scope (dbe
, GDA_DATA_MODEL (obj
));
3340 g_object_unref (obj
);
3342 /* prepare for heritage second scan */
3344 sdb_engine_get_query_by_id (dbe
,
3345 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE_WITH_INHERITS
))
3348 g_warning ("query is null");
3352 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3353 gda_query_get_query_type ((GdaQuery
*) query2
))
3355 g_warning ("non parsed sql error");
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)
3366 g_object_unref (obj
);
3371 sdb_engine_second_pass_update_heritage (dbe
, GDA_DATA_MODEL (obj
));
3375 g_object_unref (obj
);
3378 /* clean tmp heritage table */
3380 sdb_engine_get_query_by_id (dbe
,
3381 PREP_QUERY_TMP_HERITAGE_DELETE_ALL
))
3384 g_warning ("query is null");
3388 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3389 gda_query_get_query_type ((GdaQuery
*) query3
))
3391 g_warning ("non parsed sql error");
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
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,
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
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
;
3433 gint file_defined_id
= 0;
3435 gint file_position
= 0;
3436 gint is_file_scope
= 0;
3437 gchar signature
[256];
3438 gint scope_definition_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
;
3449 g_return_val_if_fail (dbe
!= NULL
, -1);
3452 /* keep it at 0 if sym_update == false */
3453 if (sym_update
== FALSE
)
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
) );
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
);
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
,
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
,
3491 gda_value_free (value
);
3496 /* parse the entry name */
3497 if (strlen (tag_entry
->name
) > sizeof (name
))
3500 ("fatal error when inserting symbol, name of symbol is too big.\n");
3501 gda_value_free (value
);
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
));
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.
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
,
3569 "typeid", value3
)) <= 0)
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
))
3583 g_warning ("query is null");
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
);
3596 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
3598 g_warning ("par_list is NULL!\n");
3599 gda_value_free (value
);
3603 /* filedefid parameter */
3605 gda_parameter_list_find_param (par_list
, "filedefid")) == NULL
)
3607 g_warning ("param filedefid is NULL from pquery!");
3608 gda_value_free (value
);
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
);
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 */
3630 gda_parameter_list_find_param (par_list
, "fileposition")) == NULL
)
3632 g_warning ("param fileposition is NULL from pquery!");
3633 gda_value_free (value
);
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 */
3644 gda_parameter_list_find_param (par_list
, "typeid")) == NULL
)
3646 g_warning ("param typeid is NULL from pquery!");
3647 gda_value_free (value
);
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
);
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
))
3670 g_warning ("query is null");
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
);
3683 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
3685 g_warning ("par_list is NULL!\n");
3686 gda_value_free (value
);
3690 /* isfilescope parameter */
3691 if ((param
= gda_parameter_list_find_param (par_list
, "symbolid"))
3694 g_warning ("param isfilescope is NULL from pquery!");
3695 gda_value_free (value
);
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
);
3706 /* isfilescope parameter */
3708 gda_parameter_list_find_param (par_list
, "isfilescope")) == NULL
)
3710 g_warning ("param isfilescope is NULL from pquery!");
3711 gda_value_free (value
);
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
);
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 */
3733 gda_parameter_list_find_param (par_list
, "scopedefinitionid")) == NULL
)
3735 g_warning ("param scopedefinitionid is NULL from pquery!");
3736 gda_value_free (value
);
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
);
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
);
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 */
3770 gda_parameter_list_find_param (par_list
, "accesskindid")) == NULL
)
3772 g_warning ("param accesskindid is NULL from pquery!");
3773 gda_value_free (value
);
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 */
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
);
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 */
3797 gda_parameter_list_find_param (par_list
, "updateflag")) == NULL
)
3799 g_warning ("param updateflag is NULL from pquery!");
3800 gda_value_free (value
);
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
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
);
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
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
);
3847 * Select * from __tmp_removed and emits removed signals.
3850 sdb_engine_detects_removed_ids (SymbolDBEngine
*dbe
)
3852 const GdaQuery
*query
, *query2
;
3853 SymbolDBEnginePriv
*priv
;
3859 g_return_if_fail (dbe
!= NULL
);
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
))
3870 g_warning ("query is null");
3874 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3875 gda_query_get_query_type ((GdaQuery
*) query
))
3877 g_warning ("non parsed sql error");
3881 obj
= G_OBJECT (gda_query_execute ((GdaQuery
*) query
, NULL
, FALSE
,
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
);
3895 g_object_unref (obj
);
3899 /* get and parse the results. */
3900 for (i
= 0; i
< num_rows
; i
++)
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
))
3917 g_warning ("query is null");
3921 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3922 gda_query_get_query_type ((GdaQuery
*) query2
))
3924 g_warning ("non parsed sql error");
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
3940 sdb_engine_update_file (SymbolDBEngine
* dbe
, const gchar
* file_on_db
)
3942 const GdaQuery
*query
;
3944 GdaParameterList
*par_list
;
3945 GdaParameter
*param
;
3948 SymbolDBEnginePriv
*priv
;
3950 g_return_if_fail (dbe
!= NULL
);
3954 if (symbol_db_engine_is_project_opened (dbe
, priv
->project_name
) == FALSE
)
3956 g_warning ("project is not opened");
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
3966 /* good. Go on with removing of old symbols, marked by a
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
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",
3983 sdb_engine_execute_non_select_sql (dbe
, 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
);
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
))
4002 g_warning ("query is null");
4006 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4007 gda_query_get_query_type ((GdaQuery
*) query
))
4009 g_warning ("non parsed sql error");
4013 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
4015 g_warning ("par_list is NULL!\n");
4019 /* filepath parameter */
4020 if ((param
= gda_parameter_list_find_param (par_list
, "filepath")) == NULL
)
4022 g_warning ("param filepath is NULL from pquery!");
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
);
4037 * @param data is a GPtrArray *files_to_scan
4038 * It will be freed when this callback will be called.
4041 on_scan_update_files_symbols_end (SymbolDBEngine
* dbe
, GPtrArray
* data
)
4043 SymbolDBEnginePriv
*priv
;
4044 GPtrArray
*files_to_scan
;
4047 DEBUG_PRINT ("on_scan_update_files_symbols_end ();");
4049 g_return_if_fail (dbe
!= NULL
);
4050 g_return_if_fail (data
!= NULL
);
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,
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
) );
4077 g_signal_handlers_disconnect_by_func (dbe
, on_scan_update_files_symbols_end
,
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.
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
;
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");
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
;
4131 /* and the project analize_time */
4132 if ((query
= sdb_engine_get_query_by_id (dbe
,
4133 PREP_QUERY_UPDATE_PROJECT_ANALIZE_TIME
))
4136 g_warning ("query is null");
4140 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4141 gda_query_get_query_type ((GdaQuery
*) query
))
4143 g_warning ("non parsed sql error");
4148 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
4150 g_warning ("par_list is NULL!\n");
4154 /* prjname parameter */
4155 if ((param
= gda_parameter_list_find_param (par_list
, "prjname"))
4158 g_warning ("param prjname is NULL from pquery!");
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
);
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.
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
;
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");
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
,
4214 gda_value_free (value
);
4218 if ((query
= sdb_engine_get_query_by_id (dbe
,
4219 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_ID
))
4222 g_warning ("query is null");
4223 gda_value_free (value
);
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
);
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
);
4242 /* prjid parameter */
4243 if ((param
= gda_parameter_list_find_param (par_list
, "prjid")) == NULL
)
4245 g_warning ("param prjname is NULL from pquery!");
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 */
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");
4264 g_object_unref (obj
);
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",
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
;
4284 time_t db_file_time
;
4286 gchar
*abs_vfs_path
;
4287 GnomeVFSHandle
*handle
;
4288 gchar timestamp
[512];
4291 gda_data_model_get_value_at_col_name (GDA_DATA_MODEL (obj
),
4292 "file_path", i
)) == NULL
)
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
,
4303 file_abs_path
= g_strdup_printf ("%s%s", priv
->data_source
,
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
) !=
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
);
4328 if (gnome_vfs_get_file_info_from_handle (handle
, file_info
,
4329 GNOME_VFS_FILE_INFO_DEFAULT
) !=
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
);
4341 gda_data_model_get_value_at_col_name (GDA_DATA_MODEL (obj
),
4342 "analize_time", i
)) == NULL
)
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;
4362 filetm
.tm_mon
= atoi (date_string
) - 1;
4364 filetm
.tm_mday
= atoi (date_string
);
4366 filetm
.tm_hour
= atoi (date_string
);
4368 filetm
.tm_min
= atoi (date_string
);
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)
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. */
4406 symbol_db_engine_remove_file (SymbolDBEngine
* dbe
, const gchar
* project
,
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");
4421 if (strlen (file
) < strlen (priv
->data_source
))
4423 g_warning ("wrong file");
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
);
4437 /* emits removed symbols signals */
4438 sdb_engine_detects_removed_ids (dbe
);
4443 on_scan_update_buffer_end (SymbolDBEngine
* dbe
, gpointer data
)
4445 SymbolDBEnginePriv
*priv
;
4446 GPtrArray
*files_to_scan
;
4449 g_return_if_fail (dbe
!= NULL
);
4450 g_return_if_fail (data
!= NULL
);
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
);
4481 g_signal_handlers_disconnect_by_func (dbe
, on_scan_update_buffer_end
,
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");
4492 sdb_engine_scan_update_buffer (SymbolDBEngine
* dbe
, gchar
* fake_file
,
4493 gchar
* text_buffer
, gint buffer_size
)
4499 /* Update symbols of a file by a memory-buffer to perform a real-time updating
4501 * real_files_list: full path on disk to 'real file' to update. e.g.
4502 * /home/foouser/fooproject/src/main.c
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
;
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
;
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");
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
;
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");
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
));
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
);
4618 symbol_db_engine_is_locked (SymbolDBEngine
* dbe
)
4620 SymbolDBEnginePriv
*priv
;
4622 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
4625 return priv
->scanning_status
;
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
;
4636 GdaCommand
*command
;
4639 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
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.");
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
);
4679 gda_command_free (command
);
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
);
4690 /* something went wrong. Our symbol cannot be retrieved coz of a
4693 final_definition_id
= -1;
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
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
;
4712 GdaCommand
*command
;
4714 gint final_definition_id
;
4716 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
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
);
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' "
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
);
4762 gda_command_free (command
);
4765 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
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
;
4870 const gchar
*real_kind
;
4872 g_return_val_if_fail (dbe
!= NULL
, NULL
);
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
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
);
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
);
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
,
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
);
4920 g_string_free (info_data
, FALSE
);
4921 g_string_free (join_data
, FALSE
);
4925 gda_command_free (command
);
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
;
4949 GdaCommand
*command
;
4951 gint scope_path_len
;
4953 gint final_definition_id
;
4957 g_return_val_if_fail (dbe
!= NULL
, NULL
);
4960 if (scope_parent_symbol_id
<= 0)
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
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
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
);
4999 gda_command_free (command
);
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
)
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
;
5037 GdaCommand
*command
;
5039 gint scope_path_len
;
5041 gint final_definition_id
;
5045 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5048 final_definition_id
= sdb_engine_walk_down_scope_path (dbe
, scope_path
);
5050 if (final_definition_id
<= 0)
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
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
);
5085 gda_command_free (command
);
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
,
5100 SymbolDBEnginePriv
*priv
;
5101 gchar
*file_escaped
;
5103 GdaCommand
*command
;
5106 g_return_val_if_fail (dbe
!= NULL
, NULL
);
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) "
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
);
5134 g_free (file_escaped
);
5138 gda_command_free (command
);
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
;
5153 GdaCommand
*command
;
5156 gint final_definition_id
;
5160 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5161 g_return_val_if_fail (file_path
!= NULL
, NULL
);
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
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
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
);
5205 gda_command_free (command
);
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
;
5220 GdaCommand
*command
;
5225 g_return_val_if_fail (dbe
!= NULL
, NULL
);
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
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
,
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
);
5258 gda_command_free (command
);
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 */
5269 symbol_db_engine_get_full_local_path (SymbolDBEngine
*dbe
, const gchar
* file
)
5271 SymbolDBEnginePriv
*priv
;
5274 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5277 /* DEBUG_PRINT ("joining %s with %s", priv->data_source, file);*/
5278 full_path
= g_strdup_printf ("%s%s", priv
->data_source
, file
);
5283 SymbolDBEngineIterator
*
5284 symbol_db_engine_find_symbol_by_name_pattern (SymbolDBEngine
*dbe
,
5285 const gchar
*name
, gint sym_info
)
5287 SymbolDBEnginePriv
*priv
;
5289 GdaCommand
*command
;
5294 g_return_val_if_fail (dbe
!= NULL
, NULL
);
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
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
,
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
);
5327 gda_command_free (command
);
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. */
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
;
5351 GdaCommand
*command
;
5353 const GValue
* value
;
5355 g_return_val_if_fail (dbe
!= NULL
, -1);
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')",
5363 DEBUG_PRINT ("symbol_db_engine_get_parent_scope_id_by_symbol_id() query is %s",
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
);
5374 DEBUG_PRINT ("BAILING OUT");
5378 gda_command_free (command
);
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
);