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 g_free (priv
->data_source
);
664 priv
->data_source
= NULL
;
666 g_free (priv
->dsn_name
);
667 priv
->dsn_name
= NULL
;
671 g_object_unref (priv
->dict
);
679 static GTimer
*sym_timer_DEBUG
= NULL
;
682 * If base_prj_path != NULL then fake_file will not be parsed. Else
683 * if fake_file is != NULL we claim and assert that tags contents which are
684 * scanned belong to the fake_file in the project.
685 * More: the fake_file refers to just one single file and cannot be used
686 * for multiple fake_files.
689 sdb_engine_populate_db_by_tags (SymbolDBEngine
* dbe
, FILE* fd
,
690 gchar
* base_prj_path
, gchar
* fake_file_on_db
,
691 gboolean force_sym_update
)
694 tagFileInfo tag_file_info
;
697 SymbolDBEnginePriv
*priv
;
699 g_return_if_fail (dbe
!= NULL
);
703 g_return_if_fail (priv
->db_connection
!= NULL
);
704 g_return_if_fail (fd
!= NULL
);
706 if (priv
->updated_symbols_id
== NULL
)
707 priv
->updated_symbols_id
= g_async_queue_new ();
709 if (priv
->inserted_symbols_id
== NULL
)
710 priv
->inserted_symbols_id
= g_async_queue_new ();
712 DEBUG_PRINT ("sdb_engine_populate_db_by_tags ()");
713 if ((tag_file
= tagsOpen_1 (fd
, &tag_file_info
)) == NULL
)
714 g_warning ("error in opening ctags file");
716 gda_connection_begin_transaction (priv
->db_connection
, "fixme", 0, NULL
);
718 if (sym_timer_DEBUG
== NULL
)
719 sym_timer_DEBUG
= g_timer_new ();
721 g_timer_reset (sym_timer_DEBUG
);
722 gint tags_total_DEBUG
= 0;
724 while (tagsNext (tag_file
, &tag_entry
) != TagFailure
)
726 sdb_engine_add_new_symbol (dbe
, &tag_entry
, fake_file_on_db
== NULL
?
727 base_prj_path
: NULL
, fake_file_on_db
,
733 gdouble elapsed_DEBUG
= g_timer_elapsed (sym_timer_DEBUG
, NULL
);
734 DEBUG_PRINT ("elapsed: %f for (%d) [%f per symbol]", elapsed_DEBUG
,
735 tags_total_DEBUG
, elapsed_DEBUG
/ tags_total_DEBUG
);
737 gda_connection_commit_transaction (priv
->db_connection
, "fixme", NULL
);
741 sdb_engine_ctags_output_callback_1 (AnjutaLauncher
* launcher
,
742 AnjutaLauncherOutputType output_type
,
743 const gchar
* chars
, gpointer user_data
)
746 gint remaining_chars
;
749 SymbolDBEnginePriv
*priv
;
752 g_return_if_fail (user_data
!= NULL
);
753 g_return_if_fail (chars
!= NULL
);
755 dbe
= (SymbolDBEngine
*)user_data
;
758 chars_ptr
= (gchar
*)chars
;
760 remaining_chars
= len_chars
= strlen (chars
);
761 len_marker
= strlen (CTAGS_MARKER
);
763 /* DEBUG_PRINT ("gotta %s", chars_ptr);*/
765 if ( len_chars
>= len_marker
)
767 gchar
*marker_ptr
= NULL
;
768 gint tmp_str_length
= 0;
770 /* is it an end file marker? */
771 marker_ptr
= strstr (chars_ptr
, CTAGS_MARKER
);
774 if (marker_ptr
!= NULL
)
778 DEBUG_PRINT ("found marker!");
780 /* set the length of the string parsed */
781 tmp_str_length
= marker_ptr
- chars_ptr
;
783 /*DEBUG_PRINT ("program output [new version]: ==>%s<==", chars_ptr);*/
784 /* write to shm_file all the chars_ptr received without the marker ones */
785 fwrite (chars_ptr
, sizeof(gchar
), tmp_str_length
, priv
->shared_mem_file
);
787 chars_ptr
= marker_ptr
+ len_marker
;
788 remaining_chars
-= (tmp_str_length
+ len_marker
);
789 fflush (priv
->shared_mem_file
);
791 /* get the scan flag from the queue. We need it to know whether
792 * an update of symbols must be done or not */
793 scan_flag
= (int)g_async_queue_try_pop (priv
->scan_queue
);
794 real_file
= g_async_queue_try_pop (priv
->scan_queue
);
796 /* and now call the populating function */
797 sdb_engine_populate_db_by_tags (dbe
, priv
->shared_mem_file
,
799 (int)real_file
== DONT_FAKE_UPDATE_SYMS
? NULL
: real_file
,
800 scan_flag
== DO_UPDATE_SYMS
? TRUE
: FALSE
);
802 /* don't forget to free the real_life, if it's a char */
803 if ((int)real_file
!= DONT_FAKE_UPDATE_SYMS
)
806 /* check also if, together with an end file marker, we have an
807 * end group-of-files end marker.
809 if ((strcmp (marker_ptr
+ len_marker
, CTAGS_MARKER
) == 0) ||
810 ftell (priv
->shared_mem_file
) <= 0)
815 /* proceed with second passes */
816 DEBUG_PRINT ("FOUND end-of-group-files marker.\n"
817 "go on with sdb_engine_second_pass_do ()");
818 sdb_engine_second_pass_do (dbe
);
820 chars_ptr
+= len_marker
;
821 remaining_chars
-= len_marker
;
824 /* Here we are. It's the right time to notify the listeners
825 * about out fresh new inserted/updated symbols...
826 * Go on by emitting them.
828 while ((tmp_inserted
= (int)
829 g_async_queue_try_pop (priv
->inserted_symbols_id
)) > 0)
831 g_signal_emit (dbe
, signals
[SYMBOL_INSERTED
], 0, tmp_inserted
);
834 while ((tmp_updated
= (int)
835 g_async_queue_try_pop (priv
->updated_symbols_id
)) > 0)
837 g_signal_emit (dbe
, signals
[SYMBOL_UPDATED
], 0, tmp_updated
);
840 /* emit signal. The end of files-group can be cannot be
841 * determined by the caller. This is the only way.
843 DEBUG_PRINT ("EMITTING scan-end");
844 g_signal_emit (dbe
, signals
[SCAN_END
], 0);
847 /* truncate the file to 0 length */
848 ftruncate (priv
->shared_mem_fd
, 0);
852 /* marker_ptr is NULL here. We should then exit the loop. */
853 /* write to shm_file all the chars received */
854 fwrite (chars_ptr
, sizeof(gchar
), remaining_chars
,
855 priv
->shared_mem_file
);
857 fflush (priv
->shared_mem_file
);
861 /* found out a new marker */
862 marker_ptr
= strstr (marker_ptr
+ len_marker
, CTAGS_MARKER
);
863 } while (remaining_chars
+ len_marker
< len_chars
);
867 DEBUG_PRINT ("no len_chars > len_marker");
872 on_scan_files_end_1 (AnjutaLauncher
* launcher
, int child_pid
,
873 int exit_status
, gulong time_taken_in_seconds
,
876 DEBUG_PRINT ("ctags ended");
880 /* Scans with ctags and produce an output 'tags' file [shared memory file]
881 * containing language symbols. This function will call ctags
882 * executale and then sdb_engine_populate_db_by_tags () when it'll detect some
884 * Please note the files_list/real_files_list parameter:
885 * this version of sdb_engine_scan_files_1 () let you scan for text buffer(s) that
886 * will be claimed as buffers for the real files.
887 * 1. simple mode: files_list represents the real files on disk and so we don't
888 * need real_files_list, which will be NULL.
889 * 2. advanced mode: files_list represents temporary flushing of buffers on disk, i.e.
890 * /tmp/anjuta_XYZ.cxx. real_files_list is the representation of those files on
891 * database. On the above example we can have anjuta_XYZ.cxx mapped as /src/main.c
892 * on db. In this mode files_list and real_files_list must have the same size.
895 /* server mode version */
897 sdb_engine_scan_files_1 (SymbolDBEngine
* dbe
, const GPtrArray
* files_list
,
898 const GPtrArray
*real_files_list
, gboolean symbols_update
)
900 SymbolDBEnginePriv
*priv
;
903 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
904 g_return_val_if_fail (files_list
!= NULL
, FALSE
);
906 if (files_list
->len
== 0)
909 /* start process in server mode */
912 if (real_files_list
!= NULL
&& (files_list
->len
!= real_files_list
->len
))
914 g_warning ("no matched size between real_files_list and files_list");
918 /* if ctags_launcher isn't initialized, then do it now. */
919 if (priv
->ctags_launcher
== NULL
)
923 DEBUG_PRINT ("creating anjuta_launcher");
924 priv
->ctags_launcher
= anjuta_launcher_new ();
926 g_signal_connect (G_OBJECT (priv
->ctags_launcher
), "child-exited",
927 G_CALLBACK (on_scan_files_end_1
), NULL
);
929 exe_string
= g_strdup_printf ("%s --fields=afmiKlnsStz "
930 "--filter=yes --filter-terminator='"CTAGS_MARKER
"'",
933 anjuta_launcher_execute (priv
->ctags_launcher
,
934 exe_string
, sdb_engine_ctags_output_callback_1
,
939 /* what about the scan_queue? is it initialized? It will contain mainly
940 * ints that refers to the force_update status.
942 if (priv
->scan_queue
== NULL
)
944 priv
->scan_queue
= g_async_queue_new ();
947 /* create the shared memory file */
948 if (priv
->shared_mem_file
== 0)
951 temp_file
= g_strdup_printf ("/anjuta-%d_%ld.tags", getpid (),
954 priv
->shared_mem_str
= temp_file
;
956 if ((priv
->shared_mem_fd
=
957 shm_open (temp_file
, O_CREAT
|O_RDWR
, S_IRUSR
|S_IWUSR
)) < 0)
959 g_warning ("Error while trying to open a shared memory file. Be"
960 "sure to have /dev/shm mounted with tmpfs");
963 priv
->shared_mem_file
= fdopen (priv
->shared_mem_fd
, "a+b");
964 DEBUG_PRINT ("temp_file %s", temp_file
);
966 /* no need to free temp_file. It will be freed on plugin finalize */
969 priv
->scanning_status
= TRUE
;
971 DEBUG_PRINT ("files_list->len %d", files_list
->len
);
973 for (i
= 0; i
< files_list
->len
; i
++)
975 gchar
*node
= (gchar
*) g_ptr_array_index (files_list
, i
);
977 if (g_file_test (node
, G_FILE_TEST_EXISTS
) == FALSE
)
979 g_warning ("File %s not scanned because it does not exist", node
);
982 DEBUG_PRINT ("anjuta_launcher_send_stdin %s", node
);
983 anjuta_launcher_send_stdin (priv
->ctags_launcher
, node
);
984 anjuta_launcher_send_stdin (priv
->ctags_launcher
, "\n");
986 if (symbols_update
== TRUE
)
987 g_async_queue_push (priv
->scan_queue
, (gpointer
) DO_UPDATE_SYMS
);
989 g_async_queue_push (priv
->scan_queue
, (gpointer
) DONT_UPDATE_SYMS
);
991 /* don't forget to add the real_files if the caller provided a list for
993 if (real_files_list
!= NULL
)
995 g_async_queue_push (priv
->scan_queue
,
997 g_ptr_array_index (real_files_list
, i
)));
1001 /* else add a DONT_FAKE_UPDATE_SYMS marker, just to noty that this is
1002 * not a fake file scan
1004 g_async_queue_push (priv
->scan_queue
, (gpointer
) DONT_FAKE_UPDATE_SYMS
);
1008 /* hack to let ctags output a marker. We will then process it into the
1009 * output callback function */
1010 anjuta_launcher_send_stdin (priv
->ctags_launcher
, "/dev/null\n");
1012 priv
->scanning_status
= FALSE
;
1020 sdb_engine_init (SymbolDBEngine
* object
)
1022 SymbolDBEngine
*sdbe
;
1024 sdbe
= SYMBOL_DB_ENGINE (object
);
1025 sdbe
->priv
= g_new0 (SymbolDBEnginePriv
, 1);
1027 /* initialize some priv data */
1028 sdbe
->priv
->gda_client
= NULL
;
1029 sdbe
->priv
->db_connection
= NULL
;
1030 sdbe
->priv
->dsn_name
= NULL
;
1031 sdbe
->priv
->project_name
= NULL
;
1032 sdbe
->priv
->data_source
= NULL
;
1034 sdbe
->priv
->scan_queue
= NULL
;
1035 sdbe
->priv
->updated_symbols_id
= NULL
;
1036 sdbe
->priv
->inserted_symbols_id
= NULL
;
1037 sdbe
->priv
->shared_mem_file
= NULL
;
1038 sdbe
->priv
->shared_mem_fd
= 0;
1039 sdbe
->priv
->shared_mem_str
= NULL
;
1040 sdbe
->priv
->scanning_status
= FALSE
;
1041 sdbe
->priv
->force_sym_update
= FALSE
;
1043 /* Initialize gda library. */
1044 gda_init ("AnjutaGda", NULL
, 0, NULL
);
1046 /* create Anjuta Launcher instance. It will be used for tags parsing. */
1047 sdbe
->priv
->ctags_launcher
= NULL
;
1051 sdb_engine_finalize (GObject
* object
)
1053 SymbolDBEngine
*dbe
;
1054 SymbolDBEnginePriv
*priv
;
1056 dbe
= SYMBOL_DB_ENGINE (object
);
1059 sdb_engine_disconnect_from_db (dbe
);
1060 sdb_engine_free_cached_queries (dbe
);
1062 g_free (priv
->project_name
);
1064 if (priv
->scan_queue
)
1066 g_async_queue_unref (priv
->scan_queue
);
1067 priv
->scan_queue
= NULL
;
1070 if (priv
->updated_symbols_id
)
1072 g_async_queue_unref (priv
->updated_symbols_id
);
1073 priv
->updated_symbols_id
= NULL
;
1077 if (priv
->inserted_symbols_id
)
1079 g_async_queue_unref (priv
->inserted_symbols_id
);
1080 priv
->inserted_symbols_id
= NULL
;
1083 if (priv
->shared_mem_file
)
1085 fclose (priv
->shared_mem_file
);
1086 priv
->shared_mem_file
= NULL
;
1090 if (priv
->shared_mem_str
)
1092 shm_unlink (priv
->shared_mem_str
);
1093 g_free (priv
->shared_mem_str
);
1094 priv
->shared_mem_str
= NULL
;
1097 if (priv
->ctags_launcher
)
1099 anjuta_launcher_signal (priv
->ctags_launcher
, SIGINT
);
1100 g_object_unref (priv
->ctags_launcher
);
1103 G_OBJECT_CLASS (parent_class
)->finalize (object
);
1107 sdb_engine_class_init (SymbolDBEngineClass
* klass
)
1109 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
1110 parent_class
= G_OBJECT_CLASS (g_type_class_peek_parent (klass
));
1112 object_class
->finalize
= sdb_engine_finalize
;
1115 = g_signal_new ("scan-end",
1116 G_OBJECT_CLASS_TYPE (object_class
),
1118 G_STRUCT_OFFSET (SymbolDBEngineClass
, scan_end
),
1120 g_cclosure_marshal_VOID__VOID
, G_TYPE_NONE
, 0);
1122 signals
[SYMBOL_INSERTED
]
1123 = g_signal_new ("symbol-inserted",
1124 G_OBJECT_CLASS_TYPE (object_class
),
1126 G_STRUCT_OFFSET (SymbolDBEngineClass
, symbol_inserted
),
1128 g_cclosure_marshal_VOID__INT
, G_TYPE_NONE
,
1132 signals
[SYMBOL_UPDATED
]
1133 = g_signal_new ("symbol-updated",
1134 G_OBJECT_CLASS_TYPE (object_class
),
1136 G_STRUCT_OFFSET (SymbolDBEngineClass
, symbol_updated
),
1138 g_cclosure_marshal_VOID__INT
, G_TYPE_NONE
,
1142 signals
[SYMBOL_REMOVED
]
1143 = g_signal_new ("symbol-removed",
1144 G_OBJECT_CLASS_TYPE (object_class
),
1146 G_STRUCT_OFFSET (SymbolDBEngineClass
, symbol_removed
),
1148 g_cclosure_marshal_VOID__INT
, G_TYPE_NONE
,
1155 sdb_engine_get_type (void)
1157 static GType our_type
= 0;
1161 static const GTypeInfo our_info
= {
1162 sizeof (SymbolDBEngineClass
), /* class_size */
1163 (GBaseInitFunc
) NULL
, /* base_init */
1164 (GBaseFinalizeFunc
) NULL
, /* base_finalize */
1165 (GClassInitFunc
) sdb_engine_class_init
, /* class_init */
1166 (GClassFinalizeFunc
) NULL
, /* class_finalize */
1167 NULL
/* class_data */ ,
1168 sizeof (SymbolDBEngine
), /* instance_size */
1169 0, /* n_preallocs */
1170 (GInstanceInitFunc
) sdb_engine_init
, /* instance_init */
1171 NULL
/* value_table */
1174 our_type
= g_type_register_static (G_TYPE_OBJECT
, "SymbolDBEngine",
1182 symbol_db_engine_new (void)
1184 SymbolDBEngine
*sdbe
;
1186 sdbe
= g_object_new (SYMBOL_TYPE_DB_ENGINE
, NULL
);
1190 /* Will create priv->db_connection, priv->gda_client.
1191 * Connect to database identified by data_source.
1192 * Usually data_source is defined also into priv. We let it here as parameter
1193 * because it is required and cannot be null.
1196 sdb_engine_connect_to_db (SymbolDBEngine
* dbe
, const gchar
* data_source
)
1198 SymbolDBEnginePriv
*priv
;
1200 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
1203 if (priv
->db_connection
!= NULL
)
1205 /* if it's the case that the connection isn't NULL, we
1206 * should notify the user
1207 * and return FALSE. It's his task to disconnect and retry to connect */
1208 g_warning ("connection is already established. Please disconnect "
1209 "and then try to reconnect.");
1213 /* create new client */
1214 priv
->gda_client
= gda_client_new ();
1216 /* establish a connection. If the sqlite file does not exist it will
1220 = gda_client_open_connection (priv
->gda_client
, data_source
,
1222 GDA_CONNECTION_OPTIONS_READ_ONLY
, NULL
);
1224 if (!GDA_IS_CONNECTION (priv
->db_connection
))
1226 g_warning ("could not open connection to %s\n", data_source
);
1230 g_message ("connected to database %s", data_source
);
1236 * Creates required tables for the database to work.
1237 * @param tables_sql_file File containing sql code.
1240 sdb_engine_create_db_tables (SymbolDBEngine
* dbe
, gchar
* tables_sql_file
)
1243 GdaCommand
*command
;
1244 SymbolDBEnginePriv
*priv
;
1248 g_return_val_if_fail (tables_sql_file
!= NULL
, FALSE
);
1252 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
1254 /* read the contents of the file */
1255 if (g_file_get_contents (tables_sql_file
, &contents
, &size
, &err
) == FALSE
)
1257 g_warning ("Something went wrong while trying to read %s",
1261 g_message ("%s", err
->message
);
1265 command
= gda_command_new (contents
, GDA_COMMAND_TYPE_SQL
,
1266 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
1267 gda_connection_execute_non_select_command (priv
->db_connection
, command
,
1269 gda_command_free (command
);
1276 * Check if the database already exists into the prj_directory
1279 symbol_db_engine_db_exists (SymbolDBEngine
* dbe
, gchar
* prj_directory
)
1281 SymbolDBEnginePriv
*priv
;
1283 g_return_val_if_fail (prj_directory
!= NULL
, FALSE
);
1287 /* check whether the db filename already exists.*/
1288 gchar
*tmp_file
= g_strdup_printf ("%s/%s.db", prj_directory
,
1291 if (g_file_test (tmp_file
, G_FILE_TEST_EXISTS
) == FALSE
)
1293 DEBUG_PRINT ("db %s does not exist", tmp_file
);
1299 DEBUG_PRINT ("db %s does exist", tmp_file
);
1304 * Open or create a new database at given directory.
1307 symbol_db_engine_open_db (SymbolDBEngine
* dbe
, gchar
* prj_directory
)
1309 SymbolDBEnginePriv
*priv
;
1310 /* Connection data */
1312 gboolean needs_tables_creation
= FALSE
;
1314 g_return_val_if_fail (prj_directory
!= NULL
, FALSE
);
1318 /* check whether the db filename already exists. If it's not the case
1319 * create the tables for the database. */
1320 gchar
*tmp_file
= g_strdup_printf ("%s/%s.db", prj_directory
,
1323 if (g_file_test (tmp_file
, G_FILE_TEST_EXISTS
) == FALSE
)
1325 needs_tables_creation
= TRUE
;
1330 priv
->data_source
= g_strdup (prj_directory
);
1332 dsn_name
= g_strdup_printf ("DB_DIR=%s;DB_NAME=%s", prj_directory
,
1335 if (gda_config_save_data_source (priv
->data_source
, "SQLite",
1336 dsn_name
, "Anjuta Project",
1337 "", "", FALSE
) == FALSE
)
1342 /* store the dsn name into Priv data. We can avoid to free it here coz it will
1343 * used later again. */
1344 priv
->dsn_name
= dsn_name
;
1346 DEBUG_PRINT ("opening/connecting to database...");
1347 sdb_engine_connect_to_db (dbe
, priv
->data_source
);
1349 if (needs_tables_creation
== TRUE
)
1351 DEBUG_PRINT ("creating tables: it needs tables...");
1352 sdb_engine_create_db_tables (dbe
, TABLES_SQL
);
1359 * @return -1 on error. Otherwise the id of table
1362 sdb_engine_get_table_id_by_unique_name (SymbolDBEngine
* dbe
, query_type qtype
,
1364 const GValue
* param_value
)
1366 const GdaQuery
*query
;
1367 GdaParameterList
*par_list
;
1368 GdaParameter
*param
;
1372 /* get prepared query */
1373 if ((query
= sdb_engine_get_query_by_id (dbe
, qtype
)) == NULL
)
1375 g_warning ("query is null");
1379 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1380 == gda_query_get_query_type ((GdaQuery
*) query
))
1382 g_warning ("sdb_engine_get_table_id_by_unique_name: non parsed "
1387 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1389 g_warning ("par_list is NULL!\n");
1393 if ((param
= gda_parameter_list_find_param (par_list
, param_key
)) == NULL
)
1395 g_warning ("sdb_engine_get_table_id_by_unique_name: param is NULL "
1400 gda_parameter_set_value (param
, param_value
);
1402 /* execute the query with parametes just set */
1404 G_OBJECT (gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
,
1407 if (!GDA_IS_DATA_MODEL (obj
) ||
1408 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj
)) <= 0)
1410 /* DEBUG_PRINT ("could not retrieve table id by unique name [par %s]",
1414 g_object_unref (obj
);
1418 /* get and parse the results. */
1419 num
= gda_data_model_get_value_at (GDA_DATA_MODEL (obj
), 0, 0);
1421 table_id
= g_value_get_int (num
);
1422 g_object_unref (obj
);
1427 * This is the same as sdb_engine_get_table_id_by_unique_name () but for two
1428 * unique parameters. This should be the quickest way. Surely quicker than
1429 * use g_strdup_printf () with a va_list for example.
1430 * @return -1 on error. Otherwise the id of table
1434 sdb_engine_get_table_id_by_unique_name2 (SymbolDBEngine
* dbe
, query_type qtype
,
1436 const GValue
* value1
,
1438 const GValue
* value2
)
1440 const GdaQuery
*query
;
1441 GdaParameterList
*par_list
;
1442 GdaParameter
*param
;
1446 /* get prepared query */
1447 if ((query
= sdb_engine_get_query_by_id (dbe
, qtype
)) == NULL
)
1449 g_warning ("query is null");
1453 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1454 == gda_query_get_query_type ((GdaQuery
*) query
))
1457 ("sdb_engine_get_table_id_by_unique_name2: non parsed sql error");
1461 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1463 g_warning ("par_list is NULL!\n");
1467 /* look for and set the first parameter */
1468 if ((param
= gda_parameter_list_find_param (par_list
, param_key1
)) == NULL
)
1470 g_warning ("sdb_engine_get_table_id_by_unique_name2: "
1471 "param is NULL from pquery! [par1: %s] [par2: %s]\n",
1472 param_key1
, param_key2
);
1476 gda_parameter_set_value (param
, value1
);
1478 /* ...and the second one */
1479 if ((param
= gda_parameter_list_find_param (par_list
, param_key2
)) == NULL
)
1481 g_warning ("param is NULL from pquery!\n");
1485 gda_parameter_set_value (param
, value2
);
1487 /* execute the query with parametes just set */
1489 G_OBJECT (gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
,
1492 if (!GDA_IS_DATA_MODEL (obj
) ||
1493 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj
)) <= 0)
1497 g_object_unref (obj
);
1501 /* get and parse the results. */
1502 num
= gda_data_model_get_value_at (GDA_DATA_MODEL (obj
), 0, 0);
1504 table_id
= g_value_get_int (num
);
1505 g_object_unref (obj
);
1510 sdb_engine_get_table_id_by_unique_name3 (SymbolDBEngine
* dbe
, query_type qtype
,
1512 const GValue
* value1
,
1514 const GValue
* value2
,
1516 const GValue
* value3
)
1518 const GdaQuery
*query
;
1519 GdaParameterList
*par_list
;
1520 GdaParameter
*param
;
1524 /* get prepared query */
1525 if ((query
= sdb_engine_get_query_by_id (dbe
, qtype
)) == NULL
)
1527 g_warning ("query is null");
1531 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1532 == gda_query_get_query_type ((GdaQuery
*) query
))
1535 ("sdb_engine_get_table_id_by_unique_name2: non parsed sql error");
1539 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1541 g_warning ("par_list is NULL!\n");
1545 /* look for and set the first parameter */
1546 if ((param
= gda_parameter_list_find_param (par_list
, param_key1
)) == NULL
)
1548 g_warning ("sdb_engine_get_table_id_by_unique_name2: "
1549 "param is NULL from pquery! [par1: %s] [par2: %s]\n",
1550 param_key1
, param_key2
);
1554 gda_parameter_set_value (param
, value1
);
1556 /* ...and the second one */
1557 if ((param
= gda_parameter_list_find_param (par_list
, param_key2
)) == NULL
)
1559 g_warning ("param is NULL from pquery!\n");
1563 gda_parameter_set_value (param
, value2
);
1565 /* ...and the third one */
1566 if ((param
= gda_parameter_list_find_param (par_list
, param_key3
)) == NULL
)
1568 g_warning ("param is NULL from pquery!\n");
1572 gda_parameter_set_value (param
, value3
);
1575 /* execute the query with parametes just set */
1577 G_OBJECT (gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
,
1580 if (!GDA_IS_DATA_MODEL (obj
) ||
1581 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj
)) <= 0)
1585 g_object_unref (obj
);
1589 /* get and parse the results. */
1590 num
= gda_data_model_get_value_at (GDA_DATA_MODEL (obj
), 0, 0);
1592 table_id
= g_value_get_int (num
);
1593 g_object_unref (obj
);
1599 symbol_db_engine_add_new_workspace (SymbolDBEngine
* dbe
,
1600 gchar
* workspace_name
)
1603 CREATE TABLE workspace (workspace_id integer PRIMARY KEY AUTOINCREMENT,
1604 workspace_name varchar (50) not null unique,
1608 const GdaQuery
*query
;
1609 GdaParameterList
*par_list
;
1610 GdaParameter
*param
;
1612 SymbolDBEnginePriv
*priv
;
1616 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
);
1657 * Return the name of the opened project.
1658 * NULL on error. Returned string must be freed by caller.
1661 symbol_db_engine_get_opened_project_name (SymbolDBEngine
* dbe
)
1663 SymbolDBEnginePriv
*priv
;
1664 g_return_val_if_fail (dbe
!= NULL
, NULL
);
1667 g_return_val_if_fail (priv
->db_connection
!= NULL
, NULL
);
1669 return g_strdup (priv
->project_name
);
1673 * Open a new project.
1674 * It will test if project was correctly created.
1677 symbol_db_engine_open_project (SymbolDBEngine
* dbe
, /*gchar* workspace, */
1678 const gchar
* project_name
)
1681 SymbolDBEnginePriv
*priv
;
1686 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
1687 if (symbol_db_engine_is_project_opened (dbe
, project_name
) == TRUE
) {
1688 g_warning ("project already opened, %s (priv %s)", project_name
,
1689 priv
->project_name
);
1693 value
= gda_value_new (G_TYPE_STRING
);
1694 g_value_set_string (value
, project_name
);
1696 /* test the existence of the project in db */
1697 if ((prj_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
1698 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME
,
1702 gda_value_free (value
);
1706 gda_value_free (value
);
1708 /* open the project... */
1709 priv
->project_name
= g_strdup (project_name
);
1716 symbol_db_engine_close_project (SymbolDBEngine
*dbe
, gchar
* project_name
)
1718 SymbolDBEnginePriv
*priv
;
1722 g_free (priv
->project_name
);
1723 priv
->project_name
= NULL
;
1725 return sdb_engine_disconnect_from_db (dbe
);
1730 * @param workspace Can be NULL. In that case a default workspace will be created,
1731 * and project will depend on that.
1732 * @param project Project name. Must NOT be NULL.
1734 // FIXME: file_include file_ignore
1736 symbol_db_engine_add_new_project (SymbolDBEngine
* dbe
, gchar
* workspace
,
1740 CREATE TABLE project (project_id integer PRIMARY KEY AUTOINCREMENT,
1741 project_name varchar (50) not null unique,
1742 wrkspace_id integer REFERENCES workspace (workspace_id),
1746 const GdaQuery
*query
;
1747 GdaParameterList
*par_list
;
1748 GdaParameter
*param
;
1750 gchar
*workspace_name
;
1752 SymbolDBEnginePriv
*priv
;
1754 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
1758 if (symbol_db_engine_is_project_opened (dbe
, project
) == TRUE
)
1760 g_warning ("You have an already opened project. Cannot continue.");
1764 if (workspace
== NULL
)
1766 workspace_name
= "anjuta_workspace_default";
1768 DEBUG_PRINT ("adding default workspace...");
1769 if (symbol_db_engine_add_new_workspace (dbe
, workspace_name
) == FALSE
)
1771 DEBUG_PRINT ("Project cannot be added because a default workspace "
1772 "cannot be created");
1778 workspace_name
= workspace
;
1781 value
= gda_value_new (G_TYPE_STRING
);
1782 g_value_set_string (value
, workspace_name
);
1784 /* get workspace id */
1785 if ((wks_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
1786 PREP_QUERY_GET_WORKSPACE_ID_BY_UNIQUE_NAME
,
1790 DEBUG_PRINT ("no workspace id");
1791 gda_value_free (value
);
1795 /* insert new project */
1797 sdb_engine_get_query_by_id (dbe
, PREP_QUERY_PROJECT_NEW
)) == NULL
)
1799 g_warning ("query is null");
1800 gda_value_free (value
);
1804 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
1805 gda_query_get_query_type ((GdaQuery
*) query
))
1807 g_warning ("non parsed sql error");
1808 gda_value_free (value
);
1812 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1814 g_warning ("par_list is NULL!\n");
1815 gda_value_free (value
);
1819 if ((param
= gda_parameter_list_find_param (par_list
, "prjname")) == NULL
)
1821 g_warning ("param prjname is NULL from pquery!");
1822 gda_value_free (value
);
1826 gda_value_reset_with_type (value
, G_TYPE_STRING
);
1827 g_value_set_string (value
, project
);
1828 gda_parameter_set_value (param
, value
);
1830 if ((param
= gda_parameter_list_find_param (par_list
, "wsid")) == NULL
)
1832 g_warning ("param is NULL from pquery!");
1836 gda_value_reset_with_type (value
, G_TYPE_INT
);
1837 g_value_set_int (value
, wks_id
);
1839 gda_parameter_set_value (param
, value
);
1841 /* execute the query with parametes just set */
1842 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
1843 gda_value_free (value
);
1850 sdb_engine_add_new_language (SymbolDBEngine
* dbe
, const gchar
*language
)
1853 CREATE TABLE language (language_id integer PRIMARY KEY AUTOINCREMENT,
1854 language_name varchar (50) not null unique);
1859 g_return_val_if_fail (language
!= NULL
, -1);
1861 value
= gda_value_new (G_TYPE_STRING
);
1862 g_value_set_string (value
, language
);
1864 /* check for an already existing table with language "name". */
1865 if ((table_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
1866 PREP_QUERY_GET_LANGUAGE_ID_BY_UNIQUE_NAME
,
1871 /* insert a new entry on db */
1872 const GdaQuery
*query
;
1873 GdaParameterList
*par_list
;
1874 GdaParameter
*param
;
1877 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_LANGUAGE_NEW
))
1880 g_warning ("query is null");
1884 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
1885 gda_query_get_query_type ((GdaQuery
*) query
))
1887 g_warning ("non parsed sql error");
1892 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1894 g_warning ("par_list is NULL!\n");
1899 gda_parameter_list_find_param (par_list
, "langname")) == NULL
)
1901 g_warning ("param langname is NULL from pquery!");
1905 value
= gda_value_new (G_TYPE_STRING
);
1906 g_value_set_string (value
, language
);
1908 gda_parameter_set_value (param
, value
);
1909 gda_value_free (value
);
1910 /* execute the query with parametes just set */
1911 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
1913 table_id
= sdb_engine_get_last_insert_id (dbe
);
1915 gda_value_free (value
);
1920 /* Add a file to project.
1921 * This function requires an opened db, i.e. calling before
1922 * symbol_db_engine_open_db ()
1923 * filepath: referes to a full file path.
1924 * WARNING: we suppose that project is already opened.
1927 sdb_engine_add_new_file (SymbolDBEngine
* dbe
, const gchar
* project
,
1928 const gchar
* filepath
, const gchar
* language
)
1931 CREATE TABLE file (file_id integer PRIMARY KEY AUTOINCREMENT,
1932 file_path TEXT not null unique,
1933 prj_id integer REFERENCES project (projec_id),
1934 lang_id integer REFERENCES language (language_id),
1938 SymbolDBEnginePriv
*priv
;
1946 value
= gda_value_new (G_TYPE_STRING
);
1947 g_value_set_string (value
, project
);
1949 /* check for an already existing table with project "project". */
1950 if ((project_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
1951 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME
,
1955 g_warning ("no project with that name exists");
1956 gda_value_free (value
);
1960 gda_value_free (value
);
1961 value
= gda_value_new (G_TYPE_STRING
);
1962 /* we're gonna set the file relative to the project folder, not the full one.
1963 * e.g.: we have a file on disk: "/tmp/foo/src/file.c" and a datasource located on
1964 * "/tmp/foo". The entry on db will be "src/file.c"
1966 g_value_set_string (value
, filepath
+ strlen(priv
->data_source
));
1968 if ((file_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
1969 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME
,
1973 /* insert a new entry on db */
1974 const GdaQuery
*query
;
1975 GdaParameterList
*par_list
;
1976 GdaParameter
*param
;
1979 language_id
= sdb_engine_add_new_language (dbe
, language
);
1981 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_FILE_NEW
))
1984 g_warning ("query is null");
1988 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
1989 gda_query_get_query_type ((GdaQuery
*) query
))
1991 g_warning ("non parsed sql error");
1996 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1998 g_warning ("par_list is NULL!\n");
2002 /* filepath parameter */
2004 gda_parameter_list_find_param (par_list
, "filepath")) == NULL
)
2006 g_warning ("param filepath is NULL from pquery!");
2010 value
= gda_value_new (G_TYPE_STRING
);
2011 /* relative filepath */
2012 g_value_set_string (value
, filepath
+ strlen(priv
->data_source
));
2013 gda_parameter_set_value (param
, value
);
2015 /* project id parameter */
2016 if ((param
= gda_parameter_list_find_param (par_list
, "prjid")) == NULL
)
2018 g_warning ("param prjid is NULL from pquery!");
2022 gda_value_reset_with_type (value
, G_TYPE_INT
);
2023 g_value_set_int (value
, project_id
);
2024 gda_parameter_set_value (param
, value
);
2026 /* language id parameter */
2028 gda_parameter_list_find_param (par_list
, "langid")) == NULL
)
2030 g_warning ("param langid is NULL from pquery!");
2034 gda_value_reset_with_type (value
, G_TYPE_INT
);
2035 g_value_set_int (value
, language_id
);
2036 gda_parameter_set_value (param
, value
);
2037 gda_value_free (value
);
2039 /* execute the query with parametes just set */
2040 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2042 gda_value_free (value
);
2049 sdb_prepare_executing_commands (SymbolDBEngine
*dbe
)
2051 GdaCommand
*command
;
2052 SymbolDBEnginePriv
*priv
;
2055 command
= gda_command_new ("PRAGMA page_size = 4096", GDA_COMMAND_TYPE_SQL
,
2056 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
2057 gda_connection_execute_non_select_command (priv
->db_connection
,
2058 command
, NULL
, NULL
);
2059 gda_command_free (command
);
2061 command
= gda_command_new ("PRAGMA cache_size = 10000", GDA_COMMAND_TYPE_SQL
,
2062 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
2063 gda_connection_execute_non_select_command (priv
->db_connection
,
2064 command
, NULL
, NULL
);
2065 gda_command_free (command
);
2067 command
= gda_command_new ("PRAGMA synchronous = OFF", GDA_COMMAND_TYPE_SQL
,
2068 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
2069 gda_connection_execute_non_select_command (priv
->db_connection
,
2070 command
, NULL
, NULL
);
2071 gda_command_free (command
);
2073 command
= gda_command_new ("PRAGMA temp_store = MEMORY", GDA_COMMAND_TYPE_SQL
,
2074 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
2075 gda_connection_execute_non_select_command (priv
->db_connection
,
2076 command
, NULL
, NULL
);
2077 gda_command_free (command
);
2083 symbol_db_engine_add_new_files (SymbolDBEngine
* dbe
, const gchar
* project
,
2084 const GPtrArray
* files_path
, const gchar
* language
,
2085 gboolean scan_symbols
)
2088 SymbolDBEnginePriv
*priv
;
2090 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
2093 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
2094 g_return_val_if_fail (project
!= NULL
, FALSE
);
2096 /* FIXME try this... */
2097 //sdb_prepare_executing_commands (dbe);
2100 if (symbol_db_engine_is_project_opened (dbe
, project
) == FALSE
)
2102 g_warning ("your project isn't opened, %s (priv %s)", project
,
2103 priv
->project_name
);
2107 for (i
= 0; i
< files_path
->len
; i
++)
2109 gchar
*node
= (gchar
*) g_ptr_array_index (files_path
, i
);
2111 /* test the existance of node file */
2112 if (g_file_test (node
, G_FILE_TEST_EXISTS
) == FALSE
)
2114 g_warning ("File %s doesn't exist", node
);
2118 /* DEBUG_PRINT ("gonna adding symbols for %s", node);*/
2120 if (sdb_engine_add_new_file (dbe
, project
, node
, language
) == FALSE
)
2122 g_warning ("Error processing file %s", node
);
2128 /* perform the scan of files. It will spawn a fork() process with
2129 * AnjutaLauncher and ctags in server mode. After the ctags cmd has been
2130 * executed, the populating process'll take place.
2133 return sdb_engine_scan_files_1 (dbe
, files_path
, NULL
, FALSE
);
2140 sdb_engine_add_new_sym_type (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
)
2143 CREATE TABLE sym_type (type_id integer PRIMARY KEY AUTOINCREMENT,
2144 type varchar (256) not null ,
2145 type_name varchar (256) not null ,
2146 unique (type, type_name)
2150 const gchar
*type_name
;
2152 GValue
*value1
, *value2
;
2154 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2156 type
= tag_entry
->kind
;
2157 type_name
= tag_entry
->name
;
2159 value1
= gda_value_new (G_TYPE_STRING
);
2160 g_value_set_string (value1
, type
);
2162 value2
= gda_value_new (G_TYPE_STRING
);
2163 g_value_set_string (value2
, type_name
);
2165 if ((table_id
= sdb_engine_get_table_id_by_unique_name2 (dbe
,
2166 PREP_QUERY_GET_SYM_TYPE_ID
,
2171 const GdaQuery
*query
;
2172 GdaParameterList
*par_list
;
2173 GdaParameter
*param
;
2176 /* it does not exist. Create a new tuple. */
2177 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SYM_TYPE_NEW
))
2180 g_warning ("query is null");
2184 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2185 gda_query_get_query_type ((GdaQuery
*) query
))
2187 g_warning ("non parsed sql error");
2192 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2194 g_warning ("par_list is NULL!\n");
2198 /* type parameter */
2199 if ((param
= gda_parameter_list_find_param (par_list
, "type")) == NULL
)
2201 g_warning ("param type is NULL from pquery!");
2205 value
= gda_value_new (G_TYPE_STRING
);
2206 g_value_set_string (value
, type
);
2207 gda_parameter_set_value (param
, value
);
2209 /* type_name parameter */
2211 gda_parameter_list_find_param (par_list
, "typename")) == NULL
)
2213 g_warning ("param typename is NULL from pquery!");
2217 gda_value_reset_with_type (value
, G_TYPE_STRING
);
2218 g_value_set_string (value
, type_name
);
2219 gda_parameter_set_value (param
, value
);
2220 gda_value_free (value
);
2222 /* execute the query with parametes just set */
2223 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2225 table_id
= sdb_engine_get_last_insert_id (dbe
);
2228 gda_value_free (value1
);
2229 gda_value_free (value2
);
2235 sdb_engine_add_new_sym_kind (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
)
2238 CREATE TABLE sym_kind (sym_kind_id integer PRIMARY KEY AUTOINCREMENT,
2239 kind_name varchar (50) not null unique
2242 const gchar
*kind_name
;
2246 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2248 kind_name
= tag_entry
->kind
;
2250 /* no kind associated with current tag */
2251 if (kind_name
== NULL
)
2254 value
= gda_value_new (G_TYPE_STRING
);
2255 g_value_set_string (value
, kind_name
);
2257 if ((table_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2258 PREP_QUERY_GET_SYM_KIND_BY_UNIQUE_NAME
,
2262 const GdaQuery
*query
;
2263 GdaParameterList
*par_list
;
2264 GdaParameter
*param
;
2267 /* not found. Go on with inserting */
2268 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SYM_KIND_NEW
))
2271 g_warning ("query is null");
2275 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2276 gda_query_get_query_type ((GdaQuery
*) query
))
2278 g_warning ("non parsed sql error");
2283 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2285 g_warning ("par_list is NULL!\n");
2289 /* kindname parameter */
2291 gda_parameter_list_find_param (par_list
, "kindname")) == NULL
)
2293 g_warning ("param kindname is NULL from pquery!");
2297 value
= gda_value_new (G_TYPE_STRING
);
2298 g_value_set_string (value
, kind_name
);
2299 gda_parameter_set_value (param
, value
);
2300 gda_value_free (value
);
2302 /* execute the query with parametes just set */
2303 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2305 table_id
= sdb_engine_get_last_insert_id (dbe
);
2307 gda_value_free (value
);
2312 sdb_engine_add_new_sym_access (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
)
2315 CREATE TABLE sym_access (access_kind_id integer PRIMARY KEY AUTOINCREMENT,
2316 access_name varchar (50) not null unique
2319 const gchar
*access
;
2323 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2325 if ((access
= tagsField (tag_entry
, "access")) == NULL
)
2327 /* no access associated with current tag */
2331 value
= gda_value_new (G_TYPE_STRING
);
2332 g_value_set_string (value
, access
);
2334 if ((table_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2335 PREP_QUERY_GET_SYM_ACCESS_BY_UNIQUE_NAME
,
2339 const GdaQuery
*query
;
2340 GdaParameterList
*par_list
;
2341 GdaParameter
*param
;
2344 /* not found. Go on with inserting */
2346 sdb_engine_get_query_by_id (dbe
,
2347 PREP_QUERY_SYM_ACCESS_NEW
)) == NULL
)
2349 g_warning ("query is null");
2353 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2354 gda_query_get_query_type ((GdaQuery
*) query
))
2356 g_warning ("non parsed sql error");
2361 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2363 g_warning ("par_list is NULL!\n");
2367 /* accesskind parameter */
2369 gda_parameter_list_find_param (par_list
, "accesskind")) == NULL
)
2371 g_warning ("param accesskind is NULL from pquery!");
2375 value
= gda_value_new (G_TYPE_STRING
);
2376 g_value_set_string (value
, access
);
2377 gda_parameter_set_value (param
, value
);
2378 gda_value_free (value
);
2380 /* execute the query with parametes just set */
2381 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2383 table_id
= sdb_engine_get_last_insert_id (dbe
);
2385 gda_value_free (value
);
2390 sdb_engine_add_new_sym_implementation (SymbolDBEngine
* dbe
,
2391 tagEntry
* tag_entry
)
2394 CREATE TABLE sym_implementation (sym_impl_id integer PRIMARY KEY AUTOINCREMENT,
2395 implementation_name varchar (50) not null unique
2398 const gchar
*implementation
;
2402 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2404 if ((implementation
= tagsField (tag_entry
, "implementation")) == NULL
)
2406 /* no implementation associated with current tag */
2410 value
= gda_value_new (G_TYPE_STRING
);
2411 g_value_set_string (value
, implementation
);
2413 if ((table_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2414 PREP_QUERY_GET_SYM_IMPLEMENTATION_BY_UNIQUE_NAME
,
2418 const GdaQuery
*query
;
2419 GdaParameterList
*par_list
;
2420 GdaParameter
*param
;
2423 /* not found. Go on with inserting */
2425 sdb_engine_get_query_by_id (dbe
,
2426 PREP_QUERY_SYM_IMPLEMENTATION_NEW
)) ==
2429 g_warning ("query is null");
2433 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2434 gda_query_get_query_type ((GdaQuery
*) query
))
2436 g_warning ("non parsed sql error");
2441 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2443 g_warning ("par_list is NULL!\n");
2447 /* implekind parameter */
2449 gda_parameter_list_find_param (par_list
, "implekind")) == NULL
)
2451 g_warning ("param implekind is NULL from pquery!");
2455 value
= gda_value_new (G_TYPE_STRING
);
2456 g_value_set_string (value
, implementation
);
2457 gda_parameter_set_value (param
, value
);
2458 gda_value_free (value
);
2460 /* execute the query with parametes just set */
2461 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2463 table_id
= sdb_engine_get_last_insert_id (dbe
);
2465 gda_value_free (value
);
2471 sdb_engine_add_new_heritage (SymbolDBEngine
* dbe
, gint base_symbol_id
,
2472 gint derived_symbol_id
)
2475 CREATE TABLE heritage (symbol_id_base integer REFERENCES symbol (symbol_id),
2476 symbol_id_derived integer REFERENCES symbol (symbol_id),
2477 PRIMARY KEY (symbol_id_base, symbol_id_derived)
2480 const GdaQuery
*query
;
2481 GdaParameterList
*par_list
;
2482 GdaParameter
*param
;
2485 g_return_if_fail (base_symbol_id
> 0);
2486 g_return_if_fail (derived_symbol_id
> 0);
2488 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_HERITAGE_NEW
))
2491 g_warning ("query is null");
2495 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2496 gda_query_get_query_type ((GdaQuery
*) query
))
2498 g_warning ("non parsed sql error");
2502 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2504 g_warning ("par_list is NULL!\n");
2508 /* symbase parameter */
2509 if ((param
= gda_parameter_list_find_param (par_list
, "symbase")) == NULL
)
2511 g_warning ("param symbase is NULL from pquery!");
2515 value
= gda_value_new (G_TYPE_INT
);
2516 g_value_set_int (value
, base_symbol_id
);
2517 gda_parameter_set_value (param
, value
);
2519 /* symderived id parameter */
2521 gda_parameter_list_find_param (par_list
, "symderived")) == NULL
)
2523 g_warning ("param symderived is NULL from pquery!");
2527 gda_value_reset_with_type (value
, G_TYPE_INT
);
2528 g_value_set_int (value
, derived_symbol_id
);
2529 gda_parameter_set_value (param
, value
);
2530 gda_value_free (value
);
2532 /* execute the query with parametes just set */
2533 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2538 sdb_engine_add_new_scope_definition (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
)
2541 CREATE TABLE scope (scope_id integer PRIMARY KEY AUTOINCREMENT,
2542 scope varchar(256) not null,
2543 type_id integer REFERENCES sym_type (type_id),
2544 unique (scope, type_id)
2548 GValue
*value1
, *value2
;
2549 gint type_table_id
, table_id
;
2551 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2552 g_return_val_if_fail (tag_entry
->kind
!= NULL
, -1);
2554 /* This symbol will define a scope which name is tag_entry->name
2555 * For example if we get a tag MyFoo with kind "namespace", it will define
2556 * the "MyFoo" scope, which type is "namespace MyFoo"
2558 scope
= tag_entry
->name
;
2560 /* filter out 'variable' and 'member' kinds. They define no scope. */
2561 if (strcmp (tag_entry
->kind
, "variable") == 0 ||
2562 strcmp (tag_entry
->kind
, "member") == 0)
2567 value1
= gda_value_new (G_TYPE_STRING
);
2568 g_value_set_string (value1
, tag_entry
->kind
);
2570 value2
= gda_value_new (G_TYPE_STRING
);
2571 g_value_set_string (value2
, scope
);
2573 /* search for type_id on sym_type table */
2574 if ((type_table_id
= sdb_engine_get_table_id_by_unique_name2 (dbe
,
2575 PREP_QUERY_GET_SYM_TYPE_ID
,
2581 /* no type has been found. */
2582 gda_value_free (value1
);
2583 gda_value_free (value2
);
2588 /* let's check for an already present scope table with scope and type_id infos. */
2589 gda_value_reset_with_type (value1
, G_TYPE_STRING
);
2590 g_value_set_string (value1
, scope
);
2592 gda_value_reset_with_type (value2
, G_TYPE_INT
);
2593 g_value_set_int (value2
, type_table_id
);
2595 if ((table_id
= sdb_engine_get_table_id_by_unique_name2 (dbe
,
2596 PREP_QUERY_GET_SCOPE_ID
,
2601 /* no luck. A table with the pair scope and type_id is not present.
2602 * ok, let's insert out new scope table.
2604 const GdaQuery
*query
;
2605 GdaParameterList
*par_list
;
2606 GdaParameter
*param
;
2609 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SCOPE_NEW
))
2612 g_warning ("query is null");
2616 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2617 gda_query_get_query_type ((GdaQuery
*) query
))
2619 g_warning ("non parsed sql error");
2624 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2626 g_warning ("par_list is NULL!\n");
2630 /* scope parameter */
2631 if ((param
= gda_parameter_list_find_param (par_list
, "scope")) == NULL
)
2633 g_warning ("param scope is NULL from pquery!");
2637 value
= gda_value_new (G_TYPE_STRING
);
2638 g_value_set_string (value
, scope
);
2639 gda_parameter_set_value (param
, value
);
2641 /* typeid parameter */
2643 gda_parameter_list_find_param (par_list
, "typeid")) == NULL
)
2645 g_warning ("param typeid is NULL from pquery!");
2649 gda_value_reset_with_type (value
, G_TYPE_INT
);
2650 g_value_set_int (value
, type_table_id
);
2651 gda_parameter_set_value (param
, value
);
2652 gda_value_free (value
);
2654 /* execute the query with parametes just set */
2655 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2657 table_id
= sdb_engine_get_last_insert_id (dbe
);
2660 gda_value_free (value1
);
2661 gda_value_free (value2
);
2666 * Saves the tagEntry info for a second pass parsing.
2667 * Usually we don't know all the symbol at the first scan of the tags. We need
2668 * a second one. These tuples are created for that purpose.
2670 * @return the table_id of the inserted tuple. -1 on error.
2673 sdb_engine_add_new_tmp_heritage_scope (SymbolDBEngine
* dbe
,
2674 tagEntry
* tag_entry
,
2675 gint symbol_referer_id
)
2678 CREATE TABLE __tmp_heritage_scope (tmp_heritage_scope_id integer PRIMARY KEY
2680 symbol_referer_id integer not null,
2681 field_inherits varchar(256) not null,
2682 field_struct varchar(256),
2683 field_typeref varchar(256),
2684 field_enum varchar(256),
2685 field_union varchar(256),
2686 field_class varchar(256),
2687 field_namespace varchar(256)
2690 const GdaQuery
*query
;
2691 GdaParameterList
*par_list
;
2692 GdaParameter
*param
;
2695 const gchar
*field_inherits
, *field_struct
, *field_typeref
,
2696 *field_enum
, *field_union
, *field_class
, *field_namespace
;
2699 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2704 if ((field_inherits
= tagsField (tag_entry
, "inherits")) == NULL
)
2706 field_inherits
= "";
2711 if ((field_struct
= tagsField (tag_entry
, "struct")) == NULL
)
2718 if ((field_typeref
= tagsField (tag_entry
, "typeref")) == NULL
)
2725 if ((field_enum
= tagsField (tag_entry
, "enum")) == NULL
)
2732 if ((field_union
= tagsField (tag_entry
, "union")) == NULL
)
2739 if ((field_class
= tagsField (tag_entry
, "class")) == NULL
)
2746 if ((field_namespace
= tagsField (tag_entry
, "namespace")) == NULL
)
2748 field_namespace
= "";
2757 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_TMP_HERITAGE_NEW
))
2760 g_warning ("query is null");
2764 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2765 gda_query_get_query_type ((GdaQuery
*) query
))
2767 g_warning ("non parsed sql error");
2771 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2773 g_warning ("par_list is NULL!\n");
2777 /* symreferid parameter */
2779 gda_parameter_list_find_param (par_list
, "symreferid")) == NULL
)
2781 g_warning ("param symreferid is NULL from pquery!");
2785 value
= gda_value_new (G_TYPE_INT
);
2786 g_value_set_int (value
, symbol_referer_id
);
2787 gda_parameter_set_value (param
, value
);
2789 /* finherits parameter */
2790 if ((param
= gda_parameter_list_find_param (par_list
, "finherits")) == NULL
)
2792 g_warning ("param finherits is NULL from pquery!");
2796 gda_value_reset_with_type (value
, G_TYPE_STRING
);
2797 g_value_set_string (value
, field_inherits
);
2798 gda_parameter_set_value (param
, value
);
2800 /* fstruct parameter */
2801 if ((param
= gda_parameter_list_find_param (par_list
, "fstruct")) == NULL
)
2803 g_warning ("param fstruct is NULL from pquery!");
2807 gda_value_reset_with_type (value
, G_TYPE_STRING
);
2808 g_value_set_string (value
, field_struct
);
2809 gda_parameter_set_value (param
, value
);
2811 /* ftyperef parameter */
2812 if ((param
= gda_parameter_list_find_param (par_list
, "ftyperef")) == NULL
)
2814 g_warning ("param ftyperef is NULL from pquery!");
2818 gda_value_reset_with_type (value
, G_TYPE_STRING
);
2819 g_value_set_string (value
, field_typeref
);
2820 gda_parameter_set_value (param
, value
);
2822 /* fenum parameter */
2823 if ((param
= gda_parameter_list_find_param (par_list
, "fenum")) == NULL
)
2825 g_warning ("param fenum is NULL from pquery!");
2829 gda_value_reset_with_type (value
, G_TYPE_STRING
);
2830 g_value_set_string (value
, field_enum
);
2831 gda_parameter_set_value (param
, value
);
2833 /* funion parameter */
2834 if ((param
= gda_parameter_list_find_param (par_list
, "funion")) == NULL
)
2836 g_warning ("param funion is NULL from pquery!");
2840 gda_value_reset_with_type (value
, G_TYPE_STRING
);
2841 g_value_set_string (value
, field_union
);
2842 gda_parameter_set_value (param
, value
);
2844 /* fclass parameter */
2845 if ((param
= gda_parameter_list_find_param (par_list
, "fclass")) == NULL
)
2847 g_warning ("param fclass is NULL from pquery!");
2851 gda_value_reset_with_type (value
, G_TYPE_STRING
);
2852 g_value_set_string (value
, field_class
);
2853 gda_parameter_set_value (param
, value
);
2855 /* fnamespace parameter */
2857 gda_parameter_list_find_param (par_list
, "fnamespace")) == NULL
)
2859 g_warning ("param fnamespace is NULL from pquery!");
2863 gda_value_reset_with_type (value
, G_TYPE_STRING
);
2864 g_value_set_string (value
, field_namespace
);
2865 gda_parameter_set_value (param
, value
);
2866 gda_value_free (value
);
2869 /* execute the query with parametes just set */
2870 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2872 table_id
= sdb_engine_get_last_insert_id (dbe
);
2877 sdb_engine_second_pass_update_scope_1 (SymbolDBEngine
* dbe
,
2878 GdaDataModel
* data
, gint data_row
,
2880 const GValue
* token_value
)
2883 GValue
*value1
, *value2
, *value
;
2884 const GValue
*value_id2
;
2886 const gchar
*tmp_str
;
2887 gchar
**tmp_str_splitted
;
2888 gint tmp_str_splitted_length
;
2889 gchar
*object_name
= NULL
;
2890 gboolean free_token_name
= FALSE
;
2891 const GdaQuery
*query
;
2892 GdaParameterList
*par_list
;
2893 GdaParameter
*param
;
2895 g_return_val_if_fail (G_VALUE_HOLDS_STRING (token_value
), FALSE
);
2897 tmp_str
= g_value_get_string (token_value
);
2899 /* we don't need empty strings */
2900 if (strcmp (tmp_str
, "") == 0)
2903 /* we could have something like "First::Second::Third::Fourth" as tmp_str, so
2904 * take only the lastscope, in this case 'Fourth'.
2906 tmp_str_splitted
= g_strsplit (tmp_str
, ":", 0);
2907 tmp_str_splitted_length
= g_strv_length (tmp_str_splitted
);
2909 if (tmp_str_splitted_length
> 0)
2911 /* handle special typedef case. Usually we have something like struct:my_foo.
2912 * splitting we have [0]-> struct [1]-> my_foo
2914 if (strcmp (token_name
, "typedef") == 0)
2916 free_token_name
= TRUE
;
2917 token_name
= g_strdup (tmp_str_splitted
[0]);
2920 object_name
= g_strdup (tmp_str_splitted
[tmp_str_splitted_length
- 1]);
2924 g_strfreev (tmp_str_splitted
);
2928 g_strfreev (tmp_str_splitted
);
2930 /* DEBUG_PRINT ("2nd pass scope: got %s %s (from %s)", token_name, object_name,
2934 value1
= gda_value_new (G_TYPE_STRING
);
2935 g_value_set_string (value1
, token_name
);
2937 value2
= gda_value_new (G_TYPE_STRING
);
2938 g_value_set_string (value2
, object_name
);
2940 if ((scope_id
= sdb_engine_get_table_id_by_unique_name2 (dbe
,
2941 PREP_QUERY_GET_SYMBOL_SCOPE_DEFINITION_ID
,
2947 if (free_token_name
)
2948 g_free (token_name
);
2950 gda_value_free (value1
);
2951 gda_value_free (value2
);
2954 gda_value_free (value1
);
2955 gda_value_free (value2
);
2957 if (free_token_name
)
2958 g_free (token_name
);
2960 /* if we reach this point we should have a good scope_id.
2961 * Go on with symbol updating.
2963 value_id2
= gda_data_model_get_value_at_col_name (data
, "symbol_referer_id",
2965 symbol_id
= g_value_get_int (value_id2
);
2967 if ((query
= sdb_engine_get_query_by_id (dbe
,
2968 PREP_QUERY_UPDATE_SYMBOL_SCOPE_ID
))
2971 g_warning ("query is null");
2975 if (GDA_QUERY_TYPE_NON_PARSED_SQL
2976 == gda_query_get_query_type ((GdaQuery
*) query
))
2978 g_warning ("non parsed sql error");
2982 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2984 g_warning ("par_list is NULL!\n");
2988 /* scopeid parameter */
2989 if ((param
= gda_parameter_list_find_param (par_list
, "scopeid")) == NULL
)
2991 g_warning ("param scopeid is NULL from pquery!");
2995 value
= gda_value_new (G_TYPE_INT
);
2996 g_value_set_int (value
, scope_id
);
2997 gda_parameter_set_value (param
, value
);
2999 /* symbolid parameter */
3000 if ((param
= gda_parameter_list_find_param (par_list
, "symbolid")) == NULL
)
3002 g_warning ("param symbolid is NULL from pquery!");
3006 gda_value_reset_with_type (value
, G_TYPE_INT
);
3007 g_value_set_int (value
, symbol_id
);
3008 gda_parameter_set_value (param
, value
);
3009 gda_value_free (value
);
3011 /* execute the query with parametes just set */
3012 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
3019 * @param data Must be filled with some values. It must have num_rows > 0
3020 * @note *CALL THIS BEFORE second_pass_update_heritage ()*
3021 * @note *DO NOT FREE data* inside this function.
3024 sdb_engine_second_pass_update_scope (SymbolDBEngine
* dbe
, GdaDataModel
* data
)
3027 * Fill up the scope.
3028 * The case: "my_foo_func_1" is the name of the current tag parsed.
3029 * Suppose we have a namespace MyFooNamespace, under which is declared
3030 * a class MyFooClass. Under that class there are some funcs like
3031 * my_foo_func_1 () etc. ctags will present us this info about
3033 * "class : MyFooNamespace::MyFooClass"
3034 * but hey! We don't need to know the namespace here, we just want to
3035 * know that my_foo_func_1 is in the scope of MyFooClass. That one will
3036 * then be mapped inside MyFooNamespace, but that's another thing.
3037 * Go on with the parsing then.
3041 for (i
= 0; i
< gda_data_model_get_n_rows (data
); i
++)
3046 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3050 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "class",
3055 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3059 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "struct",
3064 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3068 /* this is a "typedef", not a "typeref". */
3069 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "typedef",
3074 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3078 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "enum", value
);
3082 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3086 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "union",
3091 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3095 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "namespace",
3103 * @param data Must be filled with some values. It must have num_rows > 0
3104 * @note *CALL THIS AFTER second_pass_update_scope ()*
3107 sdb_engine_second_pass_update_heritage (SymbolDBEngine
* dbe
,
3108 GdaDataModel
* data
)
3111 SymbolDBEnginePriv
*priv
;
3113 g_return_if_fail (dbe
!= NULL
);
3117 for (i
= 0; i
< gda_data_model_get_n_rows (data
); i
++)
3119 const GValue
*value
;
3120 const gchar
*inherits
;
3122 gchar
**inherits_list
;
3125 value
= gda_data_model_get_value_at_col_name (data
,
3126 "field_inherits", i
);
3127 inherits
= g_value_get_string (value
);
3129 /* there can be multiple inheritance. Check that. */
3130 inherits_list
= g_strsplit (inherits
, ",", 0);
3132 if (inherits_list
!= NULL
)
3133 DEBUG_PRINT ("inherits %s\n", inherits
);
3135 /* retrieve as much info as we can from the items */
3136 for (j
= 0; j
< g_strv_length (inherits_list
); j
++)
3140 gchar
*namespace_name
;
3141 gint namespaces_length
;
3143 gint derived_klass_id
;
3144 const GValue
*value
;
3146 item
= inherits_list
[j
];
3147 DEBUG_PRINT ("heritage %s\n", item
);
3149 /* A item may have this string form:
3150 * MyFooNamespace1::MyFooNamespace2::MyFooClass
3151 * We should find the field 'MyFooNamespace2' because it's the one
3152 * that is reachable by the scope_id value of the symbol.
3155 namespaces
= g_strsplit (item
, "::", 0);
3156 namespaces_length
= g_strv_length (namespaces
);
3158 if (namespaces_length
> 1)
3160 /* this is the case in which we have the case with
3163 namespace_name
= g_strdup (namespaces
[namespaces_length
- 2]);
3164 klass_name
= g_strdup (namespaces
[namespaces_length
- 1]);
3168 /* have a last check before setting namespace_name to null.
3169 * check whether the field_namespace is void or not.
3171 const GValue
*namespace_value
;
3172 const gchar
*tmp_namespace
;
3173 gchar
**tmp_namespace_array
= NULL
;
3174 gint tmp_namespace_length
;
3177 gda_data_model_get_value_at_col_name (data
,
3178 "field_namespace", i
);
3179 tmp_namespace
= g_value_get_string (namespace_value
);
3180 if (tmp_namespace
!= NULL
)
3182 tmp_namespace_array
= g_strsplit (tmp_namespace
, "::", 0);
3183 tmp_namespace_length
= g_strv_length (tmp_namespace_array
);
3185 if (tmp_namespace_length
> 0)
3187 g_strdup (tmp_namespace_array
3188 [tmp_namespace_length
- 1]);
3190 namespace_name
= NULL
;
3194 namespace_name
= NULL
;
3197 klass_name
= g_strdup (namespaces
[namespaces_length
- 1]);
3199 g_strfreev (tmp_namespace_array
);
3202 g_strfreev (namespaces
);
3204 /* get the derived_klass_id. It should be the
3205 * symbol_referer_id field into __tmp_heritage_scope table
3207 if ((value
= (GValue
*) gda_data_model_get_value_at (data
,
3210 derived_klass_id
= g_value_get_int (value
);
3214 derived_klass_id
= 0;
3217 /* ok, search for the symbol_id of the base class */
3218 if (namespace_name
== NULL
)
3222 value1
= gda_value_new (G_TYPE_STRING
);
3223 g_value_set_string (value1
, klass_name
);
3225 if ((base_klass_id
=
3226 sdb_engine_get_table_id_by_unique_name (dbe
,
3227 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME
,
3231 gda_value_free (value1
);
3234 gda_value_free (value1
);
3239 when Libgda will parse correctly the PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME_AND_NAMESPACE
3240 query please uncomment this section and let the prepared statements do their
3245 value1 = gda_value_new (G_TYPE_STRING);
3246 g_value_set_string (value1, klass_name);
3248 value2 = gda_value_new (G_TYPE_STRING);
3249 g_value_set_string (value2, namespace_name);
3251 DEBUG_PRINT ("value1 : %s value2 : %s", klass_name, namespace_name);
3252 if ((base_klass_id =
3253 sdb_engine_get_table_id_by_unique_name2 (dbe,
3254 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME_AND_NAMESPACE,
3260 gda_value_free (value1);
3261 gda_value_free (value2);
3264 gda_value_free (value1);
3265 gda_value_free (value2);
3268 GdaCommand
*command
;
3269 GdaDataModel
*base_data
;
3272 g_strdup_printf ("SELECT symbol_id FROM symbol JOIN scope ON "
3273 "symbol.scope_id=scope.scope_id JOIN sym_type ON "
3274 "scope.type_id=sym_type.type_id WHERE "
3275 "symbol.name='%s' AND scope.scope='%s' AND "
3276 "sym_type.type='namespace'",
3277 klass_name
, namespace_name
);
3279 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
3280 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
3283 gda_connection_execute_select_command (priv
->db_connection
,
3286 gda_data_model_get_n_rows (base_data
) <= 0 )
3288 gda_command_free (command
);
3291 if (base_data
!= NULL
)
3292 g_object_unref (base_data
);
3297 value1
= (GValue
*)gda_data_model_get_value_at (base_data
, 0, 0);
3298 base_klass_id
= g_value_get_int (value1
);
3299 DEBUG_PRINT ("found base_klass_id %d", base_klass_id
);
3300 gda_command_free (command
);
3303 if (base_data
!= NULL
)
3304 g_object_unref (base_data
);
3307 g_free (namespace_name
);
3308 g_free (klass_name
);
3310 DEBUG_PRINT ("gonna sdb_engine_add_new_heritage with "
3311 "base_klass_id %d, derived_klass_id %d", base_klass_id
,
3313 sdb_engine_add_new_heritage (dbe
, base_klass_id
, derived_klass_id
);
3316 g_strfreev (inherits_list
);
3321 * Process the temporary table to update the symbols on scope and inheritance
3323 * *CALL THIS FUNCTION ONLY AFTER HAVING PARSED ALL THE TAGS ONCE*
3327 sdb_engine_second_pass_do (SymbolDBEngine
* dbe
)
3330 const GdaQuery
*query1
, *query2
, *query3
;
3332 /* prepare for scope second scan */
3334 sdb_engine_get_query_by_id (dbe
,
3335 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE
))
3338 g_warning ("query is null");
3342 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3343 gda_query_get_query_type ((GdaQuery
*) query1
))
3345 g_warning ("non parsed sql error");
3349 /* execute the query */
3350 obj
= G_OBJECT (gda_query_execute ((GdaQuery
*) query1
, NULL
, FALSE
, NULL
));
3352 if (!GDA_IS_DATA_MODEL (obj
) ||
3353 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj
)) <= 0)
3357 g_object_unref (obj
);
3362 sdb_engine_second_pass_update_scope (dbe
, GDA_DATA_MODEL (obj
));
3366 g_object_unref (obj
);
3368 /* prepare for heritage second scan */
3370 sdb_engine_get_query_by_id (dbe
,
3371 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE_WITH_INHERITS
))
3374 g_warning ("query is null");
3378 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3379 gda_query_get_query_type ((GdaQuery
*) query2
))
3381 g_warning ("non parsed sql error");
3385 /* execute the query */
3386 obj
= G_OBJECT (gda_query_execute ((GdaQuery
*) query2
, NULL
, FALSE
, NULL
));
3388 if (!GDA_IS_DATA_MODEL (obj
) ||
3389 gda_data_model_get_n_rows (GDA_DATA_MODEL (obj
)) <= 0)
3392 g_object_unref (obj
);
3397 sdb_engine_second_pass_update_heritage (dbe
, GDA_DATA_MODEL (obj
));
3401 g_object_unref (obj
);
3404 /* clean tmp heritage table */
3406 sdb_engine_get_query_by_id (dbe
,
3407 PREP_QUERY_TMP_HERITAGE_DELETE_ALL
))
3410 g_warning ("query is null");
3414 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3415 gda_query_get_query_type ((GdaQuery
*) query3
))
3417 g_warning ("non parsed sql error");
3421 /* execute the query */
3422 gda_query_execute ((GdaQuery
*) query3
, NULL
, FALSE
, NULL
);
3425 /* base_prj_path can be NULL. In that case path info tag_entry will be taken
3426 * as an absolute path.
3427 * fake_file can be used when a buffer updating is being executed. In that
3428 * particular case both base_prj_path and tag_entry->file will be ignored.
3429 * fake_file is real_path of file on disk
3432 sdb_engine_add_new_symbol (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
,
3433 gchar
* base_prj_path
, gchar
* fake_file
,
3434 gboolean sym_update
)
3437 CREATE TABLE symbol (symbol_id integer PRIMARY KEY AUTOINCREMENT,
3438 file_defined_id integer not null REFERENCES file (file_id),
3439 name varchar (256) not null,
3440 file_position integer,
3441 is_file_scope integer,
3442 signature varchar (256),
3443 scope_definition_id integer,
3445 type_id integer REFERENCES sym_type (type_id),
3446 kind_id integer REFERENCES sym_kind (sym_kind_id),
3447 access_kind_id integer REFERENCES sym_access (sym_access_id),
3448 implementation_kind_id integer REFERENCES sym_implementation
3452 SymbolDBEnginePriv
*priv
;
3453 const GdaQuery
*query
;
3454 GdaParameterList
*par_list
;
3455 GdaParameter
*param
;
3456 const gchar
*tmp_str
;
3457 gint table_id
, symbol_id
;
3458 gint file_defined_id
= 0;
3460 gint file_position
= 0;
3461 gint is_file_scope
= 0;
3462 gchar signature
[256];
3463 gint scope_definition_id
= 0;
3467 gint access_kind_id
= 0;
3468 gint implementation_kind_id
= 0;
3469 GValue
*value
, *value1
, *value2
, *value3
;
3470 gboolean sym_was_updated
= FALSE
;
3474 g_return_val_if_fail (dbe
!= NULL
, -1);
3477 /* keep it at 0 if sym_update == false */
3478 if (sym_update
== FALSE
)
3483 g_return_val_if_fail (tag_entry
!= NULL
, -1);
3485 value
= gda_value_new (G_TYPE_STRING
);
3486 if (base_prj_path
!= NULL
)
3488 /* in this case fake_file will be ignored. */
3490 /* we expect here an absolute path */
3491 g_value_set_string (value
,
3492 tag_entry
->file
+ strlen (base_prj_path
) );
3496 /* check whether the fake_file can substitute the tag_entry->file one */
3497 if (fake_file
== NULL
)
3498 g_value_set_string (value
, tag_entry
->file
);
3500 g_value_set_string (value
, fake_file
);
3503 if ((file_defined_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
3504 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME
,
3508 /* if we arrive here there should be some sync problems between the filenames
3509 * in database and the ones in the ctags files. We trust in db's ones,
3510 * so we'll just return here.
3512 g_warning ("sync problems between db and ctags filenames entries. "
3513 "File was %s (base_path: %s, fake_file: %s, tag_file: %s)",
3514 g_value_get_string (value
), base_prj_path
, fake_file
,
3516 gda_value_free (value
);
3521 /* parse the entry name */
3522 if (strlen (tag_entry
->name
) > sizeof (name
))
3525 ("fatal error when inserting symbol, name of symbol is too big.\n");
3526 gda_value_free (value
);
3531 memset (name
, 0, sizeof (name
));
3532 memcpy (name
, tag_entry
->name
, strlen (tag_entry
->name
));
3535 file_position
= tag_entry
->address
.lineNumber
;
3536 is_file_scope
= tag_entry
->fileScope
;
3538 memset (signature
, 0, sizeof (signature
));
3539 if ((tmp_str
= tagsField (tag_entry
, "signature")) != NULL
)
3541 if (strlen (tmp_str
) > sizeof (signature
))
3543 memcpy (signature
, tmp_str
, sizeof (signature
));
3547 memcpy (signature
, tmp_str
, strlen (tmp_str
));
3551 type_id
= sdb_engine_add_new_sym_type (dbe
, tag_entry
);
3554 /* scope_definition_id tells what scope this symbol defines
3555 * this call *MUST BE DONE AFTER* sym_type table population.
3557 scope_definition_id
= sdb_engine_add_new_scope_definition (dbe
, tag_entry
);
3559 /* the container scopes can be: union, struct, typeref, class, namespace etc.
3560 * this field will be parse in the second pass.
3564 kind_id
= sdb_engine_add_new_sym_kind (dbe
, tag_entry
);
3566 access_kind_id
= sdb_engine_add_new_sym_access (dbe
, tag_entry
);
3567 implementation_kind_id
=
3568 sdb_engine_add_new_sym_implementation (dbe
, tag_entry
);
3570 /* ok: was the symbol updated [at least on it's type_id/name]?
3571 * There are 3 cases:
3572 * #1. The symbol remain the same [at least on unique index key]. We will
3573 * perform only a simple update.
3574 * #2. The symbol has changed: at least on name/type/file. We will insert a
3575 * new symbol on table 'symbol'. Deletion of old one will take place
3576 * at a second stage, when a delete of all symbols with
3577 * 'tmp_flag = 0' will be done.
3578 * #3. The symbol has been deleted. As above it will be deleted at
3579 * a second stage because of the 'tmp_flag = 0'. Triggers will remove
3580 * also scope_ids and other things.
3583 value1
= gda_value_new (G_TYPE_STRING
);
3584 g_value_set_string (value1
, name
);
3586 value2
= gda_value_new (G_TYPE_INT
);
3587 g_value_set_int (value2
, file_defined_id
);
3589 value3
= gda_value_new (G_TYPE_INT
);
3590 g_value_set_int (value3
, type_id
);
3592 if ((symbol_id
= sdb_engine_get_table_id_by_unique_name3 (dbe
,
3593 PREP_QUERY_GET_SYMBOL_ID_BY_UNIQUE_INDEX_KEY
,
3596 "typeid", value3
)) <= 0)
3599 /* DEBUG_PRINT ("inserting new symbol: %s", name);*/
3600 sym_was_updated
= FALSE
;
3602 gda_value_free (value1
);
3603 gda_value_free (value2
);
3604 gda_value_free (value3
);
3606 /* create specific query for a fresh new symbol */
3607 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SYMBOL_NEW
))
3610 g_warning ("query is null");
3614 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3615 gda_query_get_query_type ((GdaQuery
*) query
))
3617 g_warning ("non parsed sql error");
3618 gda_value_free (value
);
3623 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
3625 g_warning ("par_list is NULL!\n");
3626 gda_value_free (value
);
3630 /* filedefid parameter */
3632 gda_parameter_list_find_param (par_list
, "filedefid")) == NULL
)
3634 g_warning ("param filedefid is NULL from pquery!");
3635 gda_value_free (value
);
3639 gda_value_reset_with_type (value
, G_TYPE_INT
);
3640 g_value_set_int (value
, file_defined_id
);
3641 gda_parameter_set_value (param
, value
);
3643 /* name parameter */
3644 if ((param
= gda_parameter_list_find_param (par_list
, "name")) == NULL
)
3646 g_warning ("param name is NULL from pquery!");
3647 gda_value_free (value
);
3651 gda_value_reset_with_type (value
, G_TYPE_STRING
);
3652 g_value_set_string (value
, name
);
3653 gda_parameter_set_value (param
, value
);
3655 /* fileposition parameter */
3657 gda_parameter_list_find_param (par_list
, "fileposition")) == NULL
)
3659 g_warning ("param fileposition is NULL from pquery!");
3660 gda_value_free (value
);
3664 gda_value_reset_with_type (value
, G_TYPE_INT
);
3665 g_value_set_int (value
, file_position
);
3666 gda_parameter_set_value (param
, value
);
3669 /* typeid parameter */
3671 gda_parameter_list_find_param (par_list
, "typeid")) == NULL
)
3673 g_warning ("param typeid is NULL from pquery!");
3674 gda_value_free (value
);
3678 gda_value_reset_with_type (value
, G_TYPE_INT
);
3679 g_value_set_int (value
, type_id
);
3680 gda_parameter_set_value (param
, value
);
3685 /* DEBUG_PRINT ("updating symbol: %s", name);*/
3686 sym_was_updated
= TRUE
;
3688 gda_value_free (value1
);
3689 gda_value_free (value2
);
3690 gda_value_free (value3
);
3692 /* create specific query for a fresh new symbol */
3693 if ((query
= sdb_engine_get_query_by_id (dbe
,
3694 PREP_QUERY_UPDATE_SYMBOL_ALL
))
3697 g_warning ("query is null");
3701 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3702 gda_query_get_query_type ((GdaQuery
*) query
))
3704 g_warning ("non parsed sql error");
3705 gda_value_free (value
);
3710 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
3712 g_warning ("par_list is NULL!\n");
3713 gda_value_free (value
);
3717 /* isfilescope parameter */
3718 if ((param
= gda_parameter_list_find_param (par_list
, "symbolid"))
3721 g_warning ("param isfilescope is NULL from pquery!");
3722 gda_value_free (value
);
3726 gda_value_reset_with_type (value
, G_TYPE_INT
);
3727 g_value_set_int (value
, symbol_id
);
3728 gda_parameter_set_value (param
, value
);
3733 /* isfilescope parameter */
3735 gda_parameter_list_find_param (par_list
, "isfilescope")) == NULL
)
3737 g_warning ("param isfilescope is NULL from pquery!");
3738 gda_value_free (value
);
3742 gda_value_reset_with_type (value
, G_TYPE_INT
);
3743 g_value_set_int (value
, is_file_scope
);
3744 gda_parameter_set_value (param
, value
);
3746 /* signature parameter */
3747 if ((param
= gda_parameter_list_find_param (par_list
, "signature")) == NULL
)
3749 g_warning ("param signature is NULL from pquery!");
3750 gda_value_free (value
);
3754 gda_value_reset_with_type (value
, G_TYPE_STRING
);
3755 g_value_set_string (value
, signature
);
3756 gda_parameter_set_value (param
, value
);
3758 /* scopedefinitionid parameter */
3760 gda_parameter_list_find_param (par_list
, "scopedefinitionid")) == NULL
)
3762 g_warning ("param scopedefinitionid is NULL from pquery!");
3763 gda_value_free (value
);
3767 gda_value_reset_with_type (value
, G_TYPE_INT
);
3768 g_value_set_int (value
, scope_definition_id
);
3769 gda_parameter_set_value (param
, value
);
3771 /* scopeid parameter */
3772 if ((param
= gda_parameter_list_find_param (par_list
, "scopeid")) == NULL
)
3774 g_warning ("param scopeid is NULL from pquery!");
3775 gda_value_free (value
);
3779 gda_value_reset_with_type (value
, G_TYPE_INT
);
3780 g_value_set_int (value
, scope_id
);
3781 gda_parameter_set_value (param
, value
);
3783 /* kindid parameter */
3784 if ((param
= gda_parameter_list_find_param (par_list
, "kindid")) == NULL
)
3786 g_warning ("param kindid 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
, kind_id
);
3793 gda_parameter_set_value (param
, value
);
3795 /* accesskindid parameter */
3797 gda_parameter_list_find_param (par_list
, "accesskindid")) == NULL
)
3799 g_warning ("param accesskindid 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
, access_kind_id
);
3806 gda_parameter_set_value (param
, value
);
3808 /* implementationkindid parameter */
3810 gda_parameter_list_find_param (par_list
,
3811 "implementationkindid")) == NULL
)
3813 g_warning ("param implementationkindid is NULL from pquery!");
3814 gda_value_free (value
);
3818 gda_value_reset_with_type (value
, G_TYPE_INT
);
3819 g_value_set_int (value
, implementation_kind_id
);
3820 gda_parameter_set_value (param
, value
);
3822 /* updateflag parameter */
3824 gda_parameter_list_find_param (par_list
, "updateflag")) == NULL
)
3826 g_warning ("param updateflag is NULL from pquery!");
3827 gda_value_free (value
);
3831 gda_value_reset_with_type (value
, G_TYPE_INT
);
3832 g_value_set_int (value
, update_flag
);
3833 gda_parameter_set_value (param
, value
);
3834 gda_value_free (value
);
3836 /* execute the query with parametes just set */
3837 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
3839 if (sym_was_updated
== FALSE
)
3841 table_id
= sdb_engine_get_last_insert_id (dbe
);
3843 /* This is a wrong place to emit the symbol-updated signal. Infact
3844 * db is in a inconsistent state, e.g. inheritance references are still
3846 * So add the symbol id into a queue that will be parsed once and emitted.
3848 /* g_signal_emit (dbe, signals[SYMBOL_INSERTED], 0, table_id); */
3849 g_async_queue_push (priv
->inserted_symbols_id
, (gpointer
) table_id
);
3853 table_id
= symbol_id
;
3855 /* This is a wrong place to emit the symbol-updated signal. Infact
3856 * db is in a inconsistent state, e.g. inheritance references are still
3858 * So add the symbol id into a queue that will be parsed once and emitted.
3860 /* g_signal_emit (dbe, signals[SYMBOL_UPDATED], 0, table_id); */
3861 g_async_queue_push (priv
->updated_symbols_id
, (gpointer
) table_id
);
3864 /* before returning the table_id we have to fill some infoz on temporary tables
3865 * so that in a second pass we can parse also the heritage and scope fields.
3867 sdb_engine_add_new_tmp_heritage_scope (dbe
, tag_entry
, table_id
);
3874 * Select * from __tmp_removed and emits removed signals.
3877 sdb_engine_detects_removed_ids (SymbolDBEngine
*dbe
)
3879 const GdaQuery
*query
, *query2
;
3880 SymbolDBEnginePriv
*priv
;
3884 g_return_if_fail (dbe
!= NULL
);
3888 /* ok, now we should read from __tmp_removed all the symbol ids which have
3889 * been removed, and emit a signal
3891 if ((query
= sdb_engine_get_query_by_id (dbe
,
3892 PREP_QUERY_GET_REMOVED_IDS
))
3895 g_warning ("query is null");
3899 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3900 gda_query_get_query_type ((GdaQuery
*) query
))
3902 g_warning ("non parsed sql error");
3906 obj
= G_OBJECT (gda_query_execute ((GdaQuery
*) query
, NULL
, FALSE
,
3909 if (GDA_IS_DATA_MODEL (obj
))
3911 if ((num_rows
= gda_data_model_get_n_rows (GDA_DATA_MODEL (obj
))) <= 0)
3913 g_object_unref (obj
);
3920 g_object_unref (obj
);
3924 /* get and parse the results. */
3925 for (i
= 0; i
< num_rows
; i
++)
3929 val
= gda_data_model_get_value_at (GDA_DATA_MODEL (obj
), 0, i
);
3930 tmp
= g_value_get_int (val
);
3932 g_signal_emit (dbe
, signals
[SYMBOL_REMOVED
], 0, tmp
);
3935 g_object_unref (obj
);
3937 /* let's clean the tmp_table */
3938 if ((query2
= sdb_engine_get_query_by_id (dbe
,
3939 PREP_QUERY_TMP_REMOVED_DELETE_ALL
))
3942 g_warning ("query is null");
3946 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3947 gda_query_get_query_type ((GdaQuery
*) query2
))
3949 g_warning ("non parsed sql error");
3954 gda_query_execute ((GdaQuery
*) query2
, NULL
, FALSE
, NULL
);
3959 * WARNING: do not use this function thinking that it would do a scan of symbols
3960 * too. Use symbol_db_engine_update_files_symbols () instead. This one will set
3961 * up some things on db, like removing the 'old' files which have not been
3965 sdb_engine_update_file (SymbolDBEngine
* dbe
, const gchar
* file_on_db
)
3967 const GdaQuery
*query
;
3969 GdaParameterList
*par_list
;
3970 GdaParameter
*param
;
3972 SymbolDBEnginePriv
*priv
;
3974 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
3978 if (symbol_db_engine_is_project_opened (dbe
, priv
->project_name
) == FALSE
)
3980 g_warning ("project is not opened");
3985 /* if we're updating symbols we must do some other operations on db
3986 * symbols, like remove the ones which don't have an update_flag = 1
3990 /* good. Go on with removing of old symbols, marked by a
3994 /* FIXME: libgda 3.0 doesn't have support for JOIN keyword at all on
3995 * prepared statements.
3996 * Said this we cannot expect to run queries on a really performant
4000 /* Triggers will take care of updating/deleting connected symbols
4001 * tuples, like sym_kind, sym_type etc */
4002 query_str
= g_strdup_printf ("DELETE FROM symbol WHERE "
4003 "file_defined_id = (SELECT file_id FROM file "
4004 "WHERE file_path = \"%s\") AND update_flag = 0",
4007 sdb_engine_execute_non_select_sql (dbe
, query_str
);
4010 /* emits removed symbols signals */
4011 sdb_engine_detects_removed_ids (dbe
);
4013 /* reset the update_flag to 0 */
4014 query_str
= g_strdup_printf ("UPDATE symbol SET update_flag = 0 "
4015 "WHERE file_defined_id = (SELECT file_id FROM file WHERE "
4016 "file_path = \"%s\")", file_on_db
);
4018 sdb_engine_execute_non_select_sql (dbe
, query_str
);
4021 /* last but not least, update the file analize_time */
4022 if ((query
= sdb_engine_get_query_by_id (dbe
,
4023 PREP_QUERY_UPDATE_FILE_ANALIZE_TIME
))
4026 g_warning ("query is null");
4030 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4031 gda_query_get_query_type ((GdaQuery
*) query
))
4033 g_warning ("non parsed sql error");
4037 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
4039 g_warning ("par_list is NULL!\n");
4043 /* filepath parameter */
4044 if ((param
= gda_parameter_list_find_param (par_list
, "filepath")) == NULL
)
4046 g_warning ("param filepath is NULL from pquery!");
4050 value
= gda_value_new (G_TYPE_STRING
);
4051 g_value_set_string (value
, file_on_db
);
4052 gda_parameter_set_value (param
, value
);
4054 gda_value_free (value
);
4055 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
4061 * @param data is a GPtrArray *files_to_scan
4062 * It will be freed when this callback will be called.
4065 on_scan_update_files_symbols_end (SymbolDBEngine
* dbe
, GPtrArray
* data
)
4067 SymbolDBEnginePriv
*priv
;
4068 GPtrArray
*files_to_scan
;
4071 DEBUG_PRINT ("on_scan_update_files_symbols_end ();");
4073 g_return_if_fail (dbe
!= NULL
);
4074 g_return_if_fail (data
!= NULL
);
4077 files_to_scan
= (GPtrArray
*) data
;
4079 DEBUG_PRINT ("files_to_scan->len %d", files_to_scan
->len
);
4081 for (i
= 0; i
< files_to_scan
->len
; i
++)
4083 gchar
*node
= (gchar
*) g_ptr_array_index (files_to_scan
, i
);
4085 /* DEBUG_PRINT ("processing updating node: %s, data_source: %s", node,
4087 DEBUG_PRINT ("processing updating for file %s", node +
4088 strlen (priv->data_source));*/
4090 /* clean the db from old un-updated with the last update step () */
4091 if (sdb_engine_update_file (dbe
, node
+
4092 strlen (priv
->data_source
)) == FALSE
)
4094 g_warning ("Error processing file %s", node
+
4095 strlen (priv
->data_source
) );
4101 g_signal_handlers_disconnect_by_func (dbe
, on_scan_update_files_symbols_end
,
4104 /* free the GPtrArray. */
4105 DEBUG_PRINT ("free the files_to_scan");
4106 g_ptr_array_free (files_to_scan
, TRUE
);
4107 data
= files_to_scan
= NULL
;
4108 DEBUG_PRINT ("done");
4112 /* Update symbols of saved files.
4113 * WARNING: files_path and it's contents will be freed on
4114 * on_scan_update_files_symbols_end () callback.
4117 symbol_db_engine_update_files_symbols (SymbolDBEngine
* dbe
, gchar
* project
,
4118 GPtrArray
* files_path
/*,
4119 * gchar *language */ ,
4120 gboolean update_prj_analize_time
)
4122 SymbolDBEnginePriv
*priv
;
4126 DEBUG_PRINT ("symbol_db_engine_update_files_symbols ()");
4127 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
4128 g_return_val_if_fail (project
!= NULL
, FALSE
);
4130 if (symbol_db_engine_is_project_opened (dbe
, project
) == FALSE
)
4132 g_warning ("project is not opened");
4136 /* data will be freed when callback will be called. The signal will be
4137 * disconnected too, don't worry about disconneting it by hand.
4139 g_signal_connect (G_OBJECT (dbe
), "scan-end",
4140 G_CALLBACK (on_scan_update_files_symbols_end
), files_path
);
4142 sdb_engine_scan_files_1 (dbe
, files_path
, NULL
, TRUE
);
4144 /* if true, we'll update the project scanning time too.
4145 * warning: project time scanning won't could be set before files one.
4146 * This why we'll fork the process calling sdb_engine_scan_files ()
4148 if (update_prj_analize_time
== TRUE
)
4150 const GdaQuery
*query
;
4151 GdaParameterList
*par_list
;
4152 GdaParameter
*param
;
4155 /* and the project analize_time */
4156 if ((query
= sdb_engine_get_query_by_id (dbe
,
4157 PREP_QUERY_UPDATE_PROJECT_ANALIZE_TIME
))
4160 g_warning ("query is null");
4164 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4165 gda_query_get_query_type ((GdaQuery
*) query
))
4167 g_warning ("non parsed sql error");
4172 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
4174 g_warning ("par_list is NULL!\n");
4178 /* prjname parameter */
4179 if ((param
= gda_parameter_list_find_param (par_list
, "prjname"))
4182 g_warning ("param prjname is NULL from pquery!");
4186 value
= gda_value_new (G_TYPE_STRING
);
4187 g_value_set_string (value
, priv
->project_name
);
4188 gda_parameter_set_value (param
, value
);
4190 gda_value_free (value
);
4192 DEBUG_PRINT ("updating project analize_time");
4193 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
4199 /* Update symbols of the whole project. It scans all file symbols etc.
4200 * FIXME: libgda does not support nested prepared queries like
4201 * PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_NAME. When it will do please
4202 * remember to update this function.
4205 symbol_db_engine_update_project_symbols (SymbolDBEngine
* dbe
, gchar
* project
/*,
4206 * gboolean force */ )
4208 const GdaQuery
*query
;
4209 GdaParameterList
*par_list
;
4210 GdaParameter
*param
;
4216 GPtrArray
*files_to_scan
;
4217 SymbolDBEnginePriv
*priv
;
4220 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
4221 if (symbol_db_engine_is_project_opened (dbe
, project
) == FALSE
)
4223 g_warning ("project is not opened");
4229 value
= gda_value_new (G_TYPE_STRING
);
4230 g_value_set_string (value
, project
);
4232 /* get project id */
4233 if ((project_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
4234 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME
,
4238 gda_value_free (value
);
4242 if ((query
= sdb_engine_get_query_by_id (dbe
,
4243 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_ID
))
4246 g_warning ("query is null");
4247 gda_value_free (value
);
4251 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4252 gda_query_get_query_type ((GdaQuery
*) query
))
4254 g_warning ("non parsed sql error");
4255 gda_value_free (value
);
4259 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
4261 g_warning ("par_list is NULL!\n");
4262 gda_value_free (value
);
4266 /* prjid parameter */
4267 if ((param
= gda_parameter_list_find_param (par_list
, "prjid")) == NULL
)
4269 g_warning ("param prjname is NULL from pquery!");
4273 gda_value_reset_with_type (value
, G_TYPE_INT
);
4274 g_value_set_int (value
, project_id
);
4275 gda_parameter_set_value (param
, value
);
4277 /* execute the query with parametes just set */
4279 G_OBJECT (gda_query_execute
4280 ((GdaQuery
*) query
, par_list
, FALSE
, NULL
));
4282 if (!GDA_IS_DATA_MODEL (obj
) ||
4283 (num_rows
= gda_data_model_get_n_rows (GDA_DATA_MODEL (obj
))) <= 0)
4286 g_message ("no rows");
4288 g_object_unref (obj
);
4292 /* we don't need it anymore */
4293 gda_value_free (value
);
4295 g_message ("got gda_data_model_get_n_rows (GDA_DATA_MODEL(obj)) %d",
4298 /* initialize the array */
4299 files_to_scan
= g_ptr_array_new ();
4301 /* we can now scan each filename entry to check the last modification time. */
4302 for (i
= 0; i
< num_rows
; i
++)
4304 const GValue
*value
, *value1
;
4305 const gchar
*file_name
;
4306 gchar
*file_abs_path
;
4308 time_t db_file_time
;
4310 gchar
*abs_vfs_path
;
4311 GnomeVFSHandle
*handle
;
4314 gda_data_model_get_value_at_col_name (GDA_DATA_MODEL (obj
),
4315 "file_path", i
)) == NULL
)
4320 /* build abs path. */
4321 file_name
= g_value_get_string (value
);
4322 if (priv
->data_source
!= NULL
)
4324 abs_vfs_path
= g_strdup_printf ("file://%s%s", priv
->data_source
,
4326 file_abs_path
= g_strdup_printf ("%s%s", priv
->data_source
,
4331 abs_vfs_path
= g_strdup_printf ("file://%s", file_name
);
4332 file_abs_path
= g_strdup (file_name
);
4335 GnomeVFSURI
*uri
= gnome_vfs_uri_new (abs_vfs_path
);
4336 GnomeVFSFileInfo
*file_info
= gnome_vfs_file_info_new ();
4338 /* retrieve data/time info */
4339 if (gnome_vfs_open_uri (&handle
, uri
,
4340 GNOME_VFS_OPEN_READ
| GNOME_VFS_OPEN_RANDOM
) !=
4343 g_message ("could not open URI %s", abs_vfs_path
);
4344 gnome_vfs_uri_unref (uri
);
4345 gnome_vfs_file_info_unref (file_info
);
4346 g_free (abs_vfs_path
);
4347 g_free (file_abs_path
);
4351 if (gnome_vfs_get_file_info_from_handle (handle
, file_info
,
4352 GNOME_VFS_FILE_INFO_DEFAULT
) !=
4355 g_message ("cannot get file info from handle");
4356 gnome_vfs_close (handle
);
4357 gnome_vfs_uri_unref (uri
);
4358 gnome_vfs_file_info_unref (file_info
);
4359 g_free (file_abs_path
);
4364 gda_data_model_get_value_at_col_name (GDA_DATA_MODEL (obj
),
4365 "analize_time", i
)) == NULL
)
4370 /* weirdly we have a strange libgda behaviour here too.
4371 * as from ChangeLog GDA_TYPE_TIMESTAMP as SQLite does not impose a
4372 * known format for dates (there is no date datatype).
4373 * We have then to do some hackery to retrieve the date.
4375 date_string
= (gchar
*) g_value_get_string (value1
);
4377 DEBUG_PRINT ("processing for upating symbol %s", file_name
);
4378 DEBUG_PRINT ("date_string %s", date_string
);
4380 /* fill a struct tm with the date retrieved by the string. */
4381 /* string is something like '2007-04-18 23:51:39' */
4382 memset (&filetm
, 0, sizeof (struct tm
));
4383 filetm
.tm_year
= atoi (date_string
) - 1900;
4385 filetm
.tm_mon
= atoi (date_string
) - 1;
4387 filetm
.tm_mday
= atoi (date_string
);
4389 filetm
.tm_hour
= atoi (date_string
);
4391 filetm
.tm_min
= atoi (date_string
);
4393 filetm
.tm_sec
= atoi (date_string
);
4395 /* subtract one hour to the db_file_time. (why this?) */
4396 db_file_time
= mktime (&filetm
) - 3600;
4398 if (difftime (db_file_time
, file_info
->mtime
) <= 0)
4400 g_message ("to be added! : %s", file_name
);
4401 g_ptr_array_add (files_to_scan
, file_abs_path
);
4404 DEBUG_PRINT ("difftime %f", difftime (db_file_time, file_info->mtime));
4405 DEBUG_PRINT ("db_file_time %d - "
4406 "file_info->mtime %d "
4407 "file_info->ctime %d", db_file_time,
4408 file_info->mtime, file_info->ctime);
4410 gnome_vfs_close (handle
);
4411 gnome_vfs_uri_unref (uri
);
4412 gnome_vfs_file_info_unref (file_info
);
4413 g_free (abs_vfs_path
);
4414 /* no need to free file_abs_path, it's been added to files_to_scan */
4417 if (files_to_scan
->len
> 0)
4419 /* at the end let's the scanning function do its job */
4420 return symbol_db_engine_update_files_symbols (dbe
, project
,
4421 files_to_scan
, TRUE
);
4427 /* Remove a file, together with its symbols, from a project. */
4429 symbol_db_engine_remove_file (SymbolDBEngine
* dbe
, const gchar
* project
,
4433 SymbolDBEnginePriv
*priv
;
4435 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
4436 if (symbol_db_engine_is_project_opened (dbe
, project
) == FALSE
)
4438 g_warning ("project is not opened");
4444 if (strlen (file
) < strlen (priv
->data_source
))
4446 g_warning ("wrong file");
4450 /* Triggers will take care of updating/deleting connected symbols
4451 * tuples, like sym_kind, sym_type etc */
4452 query_str
= g_strdup_printf ("DELETE FROM file WHERE prj_id "
4453 "= (SELECT project_id FROM project WHERE project_name = '%s') AND "
4454 "file_path = '%s'", project
, file
+ strlen (priv
->data_source
));
4456 /* DEBUG_PRINT ("symbol_db_engine_remove_file () : %s", query_str);*/
4457 sdb_engine_execute_non_select_sql (dbe
, query_str
);
4460 /* emits removed symbols signals */
4461 sdb_engine_detects_removed_ids (dbe
);
4467 on_scan_update_buffer_end (SymbolDBEngine
* dbe
, gpointer data
)
4469 SymbolDBEnginePriv
*priv
;
4470 GPtrArray
*files_to_scan
;
4473 g_return_if_fail (dbe
!= NULL
);
4474 g_return_if_fail (data
!= NULL
);
4477 files_to_scan
= (GPtrArray
*) data
;
4479 DEBUG_PRINT ("files_to_scan->len %d", files_to_scan
->len
);
4481 for (i
= 0; i
< files_to_scan
->len
; i
++)
4483 gchar
*node
= (gchar
*) g_ptr_array_index (files_to_scan
, i
);
4485 DEBUG_PRINT ("processing updating for file [on disk] %s, "
4486 "passed to on_scan_update_buffer_end (): %s",
4487 node
, node
+ strlen (priv
->data_source
));
4489 if (sdb_engine_update_file (dbe
, node
+
4490 strlen (priv
->data_source
)) == FALSE
)
4492 g_warning ("Error processing file %s", node
);
4498 g_signal_handlers_disconnect_by_func (dbe
, on_scan_update_buffer_end
,
4501 /* free the GPtrArray. */
4502 DEBUG_PRINT ("free the files_to_scan");
4503 g_ptr_array_free (files_to_scan
, TRUE
);
4504 data
= files_to_scan
= NULL
;
4505 DEBUG_PRINT ("done");
4508 /* Update symbols of a file by a memory-buffer to perform a real-time updating
4510 * real_files_list: full path on disk to 'real file' to update. e.g.
4511 * /home/foouser/fooproject/src/main.c
4514 symbol_db_engine_update_buffer_symbols (SymbolDBEngine
* dbe
, gchar
* project
,
4515 GPtrArray
* real_files_list
,
4516 const GPtrArray
* text_buffers
,
4517 const GPtrArray
* buffer_sizes
)
4519 SymbolDBEnginePriv
*priv
;
4522 DEBUG_PRINT ("symbol_db_engine_update_buffer_symbols ()");
4524 /* array that'll represent the /dev/shm/anjuta-XYZ files */
4525 GPtrArray
*temp_files
;
4526 GPtrArray
*real_files_on_db
;
4530 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
4531 g_return_val_if_fail (project
!= NULL
, FALSE
);
4532 g_return_val_if_fail (real_files_list
!= NULL
, FALSE
);
4533 g_return_val_if_fail (text_buffers
!= NULL
, FALSE
);
4534 g_return_val_if_fail (buffer_sizes
!= NULL
, FALSE
);
4536 if (symbol_db_engine_is_project_opened (dbe
, project
) == FALSE
)
4538 g_warning ("project is not opened");
4542 temp_files
= g_ptr_array_new();
4543 real_files_on_db
= g_ptr_array_new();
4545 /* obtain a GPtrArray with real_files on database */
4546 for (i
=0; i
< real_files_list
->len
; i
++)
4548 gchar
*new_node
= (gchar
*)g_ptr_array_index (real_files_list
, i
)
4549 + strlen(priv
->data_source
);
4550 DEBUG_PRINT ("real_file on db: %s", new_node
);
4551 g_ptr_array_add (real_files_on_db
, g_strdup (new_node
));
4554 /* create a temporary file for each buffer */
4555 for (i
=0; i
< real_files_list
->len
; i
++)
4557 FILE *shared_mem_file
;
4558 const gchar
*temp_buffer
;
4562 gchar
*base_filename
;
4563 const gchar
*curr_real_file
;
4565 curr_real_file
= g_ptr_array_index (real_files_list
, i
);
4567 /* it's ok to have just the base filename to create the
4568 * target buffer one */
4569 base_filename
= g_filename_display_basename (curr_real_file
);
4571 temp_file
= g_strdup_printf ("/anjuta-%d-%ld-%s", getpid (),
4572 time (NULL
), base_filename
);
4573 g_free (base_filename
);
4575 DEBUG_PRINT ("my temp file is %s", temp_file
);
4576 if ((shared_mem_fd
=
4577 shm_open (temp_file
, O_CREAT
|O_RDWR
, S_IRUSR
|S_IWUSR
)) < 0)
4579 g_warning ("Error while trying to open a shared memory file. Be"
4580 "sure to have /dev/shm mounted with tmpfs");
4584 shared_mem_file
= fdopen (shared_mem_fd
, "w+b");
4586 DEBUG_PRINT ("temp_file %s", temp_file
);
4588 temp_buffer
= g_ptr_array_index (text_buffers
, i
);
4589 temp_size
= (gint
)g_ptr_array_index (buffer_sizes
, i
);
4590 fwrite (temp_buffer
, sizeof(gchar
), temp_size
, shared_mem_file
);
4591 fflush (shared_mem_file
);
4592 fclose (shared_mem_file
);
4594 /* add the temp file to the array. */
4595 g_ptr_array_add (temp_files
, g_strdup_printf ("/dev/shm%s", temp_file
));
4600 /* data will be freed when callback will be called. The signal will be
4601 * disconnected too, don't worry about disconneting it by hand.
4603 g_signal_connect (G_OBJECT (dbe
), "scan-end",
4604 G_CALLBACK (on_scan_update_buffer_end
), real_files_list
);
4606 sdb_engine_scan_files_1 (dbe
, temp_files
, real_files_on_db
, TRUE
);
4608 /* let's free the temp_files array */
4609 for (i
=0; i
< temp_files
->len
; i
++)
4610 g_free (g_ptr_array_index (temp_files
, i
));
4612 g_ptr_array_free (temp_files
, TRUE
);
4614 /* and the real_files_on_db too */
4615 for (i
=0; i
< real_files_on_db
->len
; i
++)
4616 g_free (g_ptr_array_index (real_files_on_db
, i
));
4618 g_ptr_array_free (real_files_on_db
, TRUE
);
4625 symbol_db_engine_is_locked (SymbolDBEngine
* dbe
)
4627 SymbolDBEnginePriv
*priv
;
4629 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
4632 return priv
->scanning_status
;
4636 sdb_engine_walk_down_scope_path (SymbolDBEngine
*dbe
, const GPtrArray
* scope_path
)
4638 SymbolDBEnginePriv
*priv
;
4639 gint final_definition_id
;
4640 gint scope_path_len
;
4643 GdaCommand
*command
;
4646 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
4649 scope_path_len
= scope_path
->len
;
4651 /* we'll return if the length is even or minor than 3 */
4652 if (scope_path_len
< 3 || scope_path_len
% 2 == 0)
4654 g_warning ("bad scope_path.");
4658 final_definition_id
= 0;
4659 for (i
=0; i
< scope_path_len
-1; i
= i
+ 2)
4661 const GValue
*value
;
4662 DEBUG_PRINT ("loop final_definition_id %d", final_definition_id
);
4664 query_str
= g_strdup_printf ("SELECT scope_definition_id FROM symbol "
4665 "WHERE scope_id = '%d' AND scope_definition_id = ("
4666 "SELECT scope.scope_id FROM scope "
4667 "INNER JOIN sym_type ON scope.type_id = sym_type.type_id "
4668 "WHERE sym_type.type = '%s' "
4669 "AND scope.scope = '%s'"
4670 ")", final_definition_id
, (gchar
*)g_ptr_array_index (scope_path
, i
),
4671 (gchar
*)g_ptr_array_index (scope_path
, i
+ 1));
4673 DEBUG_PRINT ("walk down query is %s", query_str
);
4674 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
4675 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
4677 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
4678 command
, NULL
, NULL
)) == NULL
||
4679 gda_data_model_get_n_rows (data
) <= 0 )
4681 gda_command_free (command
);
4686 gda_command_free (command
);
4689 value
= gda_data_model_get_value_at (data
, 0, 0);
4690 if (G_VALUE_HOLDS (value
, G_TYPE_INT
))
4692 final_definition_id
= g_value_get_int (value
);
4693 g_object_unref (data
);
4697 /* something went wrong. Our symbol cannot be retrieved coz of a
4700 final_definition_id
= -1;
4705 return final_definition_id
;
4708 /* Returns an iterator to the data retrieved from database.
4709 * The iterator, if not null, will contain a list of parent classes for the given
4711 * namespace_name can be NULL.
4713 SymbolDBEngineIterator
*
4714 symbol_db_engine_get_class_parents (SymbolDBEngine
*dbe
, gchar
*klass_name
,
4715 const GPtrArray
*scope_path
)
4717 SymbolDBEnginePriv
*priv
;
4719 GdaCommand
*command
;
4721 gint final_definition_id
;
4723 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
4726 final_definition_id
= -1;
4727 if (scope_path
!= NULL
)
4728 final_definition_id
= sdb_engine_walk_down_scope_path (dbe
, scope_path
);
4730 /* FIXME: as always prepared queries of this complexity gives
4731 GDA_QUERY_TYPE_NON_PARSED_SQL error. */
4732 if (final_definition_id
> 0)
4734 query_str
= g_strdup_printf("SELECT symbol.symbol_id, symbol.name FROM heritage "
4735 "JOIN symbol ON heritage.symbol_id_base = symbol.symbol_id "
4736 "WHERE symbol_id_derived = ("
4737 "SELECT symbol_id FROM symbol "
4738 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id "
4739 "WHERE symbol.name = '%s' "
4740 "AND sym_kind.kind_name = 'class' "
4741 "AND symbol.scope_id = '%d'"
4742 ")", klass_name
, final_definition_id
);
4746 query_str
= g_strdup_printf("SELECT symbol.symbol_id, symbol.name FROM heritage "
4747 "JOIN symbol ON heritage.symbol_id_base = symbol.symbol_id "
4748 "WHERE symbol_id_derived = ("
4749 "SELECT symbol_id FROM symbol "
4750 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id "
4751 "WHERE symbol.name = '%s' "
4752 "AND sym_kind.kind_name = 'class' "
4756 DEBUG_PRINT ("get parents query: %s", query_str
);
4757 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
4758 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
4760 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
4761 command
, NULL
, NULL
)) == NULL
||
4762 gda_data_model_get_n_rows (data
) <= 0 )
4764 gda_command_free (command
);
4769 gda_command_free (command
);
4772 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
4776 sdb_engine_prepare_symbol_info_sql (SymbolDBEngine
*dbe
, GString
*info_data
,
4777 GString
*join_data
, gint sym_info
)
4779 if (sym_info
& SYMINFO_FILE_PATH
||
4780 sym_info
& SYMINFO_LANGUAGE
||
4781 sym_info
& SYMINFO_PROJECT_NAME
||
4782 sym_info
& SYMINFO_FILE_IGNORE
||
4783 sym_info
& SYMINFO_FILE_INCLUDE
)
4785 info_data
= g_string_append (info_data
, ",file.file_path ");
4786 join_data
= g_string_append (join_data
, "LEFT JOIN file ON "
4787 "symbol.file_defined_id = file.file_id ");
4790 if (sym_info
& SYMINFO_LANGUAGE
)
4792 info_data
= g_string_append (info_data
, ",language.language_name ");
4793 join_data
= g_string_append (join_data
, "LEFT JOIN language ON "
4794 "file.lang_id = language.language_id ");
4797 if (sym_info
& SYMINFO_IMPLEMENTATION
)
4799 info_data
= g_string_append (info_data
, ",sym_implementation.implementation_name ");
4800 join_data
= g_string_append (join_data
, "LEFT JOIN sym_implementation ON "
4801 "symbol.implementation_kind_id = sym_implementation.sym_impl_id ");
4804 if (sym_info
& SYMINFO_ACCESS
)
4806 info_data
= g_string_append (info_data
, ",sym_access.access_name ");
4807 join_data
= g_string_append (join_data
, "LEFT JOIN sym_access ON "
4808 "symbol.access_kind_id = sym_access.access_kind_id ");
4811 if (sym_info
& SYMINFO_KIND
)
4813 info_data
= g_string_append (info_data
, ",sym_kind.kind_name ");
4814 join_data
= g_string_append (join_data
, "LEFT JOIN sym_kind ON "
4815 "symbol.kind_id = sym_kind.sym_kind_id ");
4818 if (sym_info
& SYMINFO_TYPE
|| sym_info
& SYMINFO_TYPE_NAME
)
4820 info_data
= g_string_append (info_data
, ",sym_type.type,"
4821 "sym_type.type_name ");
4822 join_data
= g_string_append (join_data
, "LEFT JOIN sym_type ON "
4823 "symbol.type_id = sym_type.type_id ");
4826 if (sym_info
& SYMINFO_PROJECT_NAME
||
4827 sym_info
& SYMINFO_FILE_IGNORE
||
4828 sym_info
& SYMINFO_FILE_INCLUDE
)
4830 info_data
= g_string_append (info_data
, ",project.project_name ");
4831 join_data
= g_string_append (join_data
, "LEFT JOIN project ON "
4832 "file.prj_id = project.project_id ");
4835 if (sym_info
& SYMINFO_FILE_IGNORE
)
4837 info_data
= g_string_append (info_data
, ",file_ignore.type AS file_ignore_type ");
4838 join_data
= g_string_append (join_data
, "LEFT JOIN ext_ignore ON "
4839 "ext_ignore.prj_id = project.project_id "
4840 "LEFT JOIN file_ignore ON "
4841 "ext_ignore.file_ign_id = file_ignore.file_ignore_id ");
4844 if (sym_info
& SYMINFO_FILE_INCLUDE
)
4846 info_data
= g_string_append (info_data
, ",file_include.type AS file_include_type ");
4847 join_data
= g_string_append (join_data
, "LEFT JOIN ext_include ON "
4848 "ext_include.prj_id = project.project_id "
4849 "LEFT JOIN file_include ON "
4850 "ext_include.file_incl_id = file_include.file_include_id ");
4853 /* TODO, or better.. TAKE A DECISION
4854 if (sym_info & SYMINFO_WORKSPACE_NAME)
4856 info_data = g_string_append (info_data, ",sym_access.access_name ");
4857 join_data = g_string_append (info_data, "LEFT JOIN sym_kind ON "
4858 "symbol.kind_id = sym_kind.sym_kind_id ");
4864 * kind can be NULL. In that case we'll return all the kinds of symbols found
4865 * at root level [global level].
4867 SymbolDBEngineIterator
*
4868 symbol_db_engine_get_global_members (SymbolDBEngine
*dbe
,
4869 const gchar
*kind
, gint sym_info
)
4871 SymbolDBEnginePriv
*priv
;
4872 GdaCommand
*command
;
4878 g_return_val_if_fail (dbe
!= NULL
, NULL
);
4881 /* check for an already flagged sym_info with KIND. SYMINFO_KIND on sym_info
4882 * is already contained into the default query infos.
4884 sym_info
= sym_info
& ~SYMINFO_KIND
;
4886 /* info_data contains the stuff after SELECT and befor FROM */
4887 info_data
= g_string_new ("");
4889 /* join_data contains the optionals joins to do to retrieve new data on other
4892 join_data
= g_string_new ("");
4894 /* fill info_data and join data with optional sql */
4895 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
4899 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, "
4900 "symbol.name, symbol.file_position, symbol.is_file_scope, "
4901 "symbol.signature, sym_kind.kind_name %s FROM symbol "
4902 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id %s "
4903 "WHERE scope_id <= 0", info_data
->str
, join_data
->str
);
4907 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
4908 "symbol.file_position, "
4909 "symbol.is_file_scope, symbol.signature %s FROM symbol "
4910 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id %s "
4911 "WHERE scope_id <= 0 "
4912 "AND sym_kind.kind_name = '%s'", info_data
->str
, join_data
->str
,
4916 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
4917 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
4919 /* DEBUG_PRINT ("query is %s", query_str);*/
4920 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
4921 command
, NULL
, NULL
)) == NULL
||
4922 gda_data_model_get_n_rows (data
) <= 0 )
4924 gda_command_free (command
);
4926 g_string_free (info_data
, FALSE
);
4927 g_string_free (join_data
, FALSE
);
4931 gda_command_free (command
);
4933 g_string_free (info_data
, FALSE
);
4934 g_string_free (join_data
, FALSE
);
4936 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
4942 * Sometimes it's useful going to query just with ids [and so integers] to have
4943 * a little speed improvement.
4945 SymbolDBEngineIterator
*
4946 symbol_db_engine_get_scope_members_by_symbol_id (SymbolDBEngine
*dbe
,
4947 gint scope_parent_symbol_id
, gint sym_info
)
4950 select b.* from symbol a, symbol b where a.symbol_id = 348 and
4951 b.scope_id = a.scope_definition_id;
4953 SymbolDBEnginePriv
*priv
;
4955 GdaCommand
*command
;
4960 g_return_val_if_fail (dbe
!= NULL
, NULL
);
4963 if (scope_parent_symbol_id
<= 0)
4966 /* info_data contains the stuff after SELECT and befor FROM */
4967 info_data
= g_string_new ("");
4969 /* join_data contains the optionals joins to do to retrieve new data on other
4972 join_data
= g_string_new ("");
4974 /* fill info_data and join data with optional sql */
4975 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
4977 /* ok, beware that we use an 'alias hack' to accomplish compatibility with
4978 * sdb_engine_prepare_symbol_info_sql () function. In particular we called
4979 * the first joining table 'a', the second one 'symbol', where is the info we
4982 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
4983 "symbol.file_position, "
4984 "symbol.is_file_scope, symbol.signature %s FROM symbol a, symbol symbol "
4985 "%s WHERE a.symbol_id = '%d' AND symbol.scope_id = a.scope_definition_id "
4986 "AND symbol.scope_id > 0", info_data
->str
, join_data
->str
,
4987 scope_parent_symbol_id
);
4989 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
4990 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
4991 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
4993 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
4994 command
, NULL
, NULL
)) == NULL
||
4995 gda_data_model_get_n_rows (data
) <= 0 )
4997 gda_command_free (command
);
5002 gda_command_free (command
);
5004 g_string_free (info_data
, FALSE
);
5005 g_string_free (join_data
, FALSE
);
5007 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5010 /* scope_path cannot be NULL.
5011 * scope_path will be something like "scope1_kind", "scope1_name", "scope2_kind",
5012 * "scope2_name", NULL
5014 SymbolDBEngineIterator
*
5015 symbol_db_engine_get_scope_members (SymbolDBEngine
*dbe
,
5016 const GPtrArray
* scope_path
, gint sym_info
)
5021 select * from symbol where scope_id = (
5022 select scope.scope_id from scope
5023 inner join sym_type on scope.type_id = sym_type.type_id
5024 where sym_type.type = 'class'
5025 and scope.scope = 'MyClass'
5028 select * from symbol where scope_id = (
5029 select scope.scope_id from scope
5030 inner join sym_type on scope.type_id = sym_type.type_id
5031 where sym_type.type = 'struct'
5032 and scope.scope = '_faa_1');
5035 es. scope_path = First, namespace, Second, namespace, NULL,
5036 symbol_name = Second_1_class
5038 SymbolDBEnginePriv
*priv
;
5040 GdaCommand
*command
;
5042 gint final_definition_id
;
5046 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5049 final_definition_id
= sdb_engine_walk_down_scope_path (dbe
, scope_path
);
5051 if (final_definition_id
<= 0)
5056 /* info_data contains the stuff after SELECT and befor FROM */
5057 info_data
= g_string_new ("");
5059 /* join_data contains the optionals joins to do to retrieve new data on other
5062 join_data
= g_string_new ("");
5064 /* fill info_data and join data with optional sql */
5065 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
5067 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5068 "symbol.file_position, "
5069 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5070 "%s WHERE scope_id = '%d'", info_data
->str
, join_data
->str
,
5071 final_definition_id
);
5073 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
5074 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
5075 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
5077 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
5078 command
, NULL
, NULL
)) == NULL
||
5079 gda_data_model_get_n_rows (data
) <= 0 )
5081 gda_command_free (command
);
5086 gda_command_free (command
);
5088 g_string_free (info_data
, FALSE
);
5089 g_string_free (join_data
, FALSE
);
5091 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5094 /* Returns an iterator to the data retrieved from database.
5095 * It will be possible to get the scope specified by the line of the file.
5097 SymbolDBEngineIterator
*
5098 symbol_db_engine_get_current_scope (SymbolDBEngine
*dbe
, const gchar
* filename
,
5101 SymbolDBEnginePriv
*priv
;
5102 gchar
*file_escaped
;
5104 GdaCommand
*command
;
5107 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5111 file_escaped
= g_strescape (filename
, NULL
);
5113 /* WARNING: probably there can be some problems with escaping file names here.
5114 * They should come already escaped as from project db.
5116 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5117 "symbol.file_position, "
5118 "symbol.is_file_scope, symbol.signature, MIN('%d' - symbol.file_position) "
5120 "JOIN file ON file_defined_id = file_id "
5121 "WHERE file.file_path = \"%s\" "
5122 "AND '%d' - symbol.file_position >= 0", (gint
)line
, file_escaped
,
5125 DEBUG_PRINT ("current_scope query is %s", query_str
);
5127 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
5128 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
5130 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
5131 command
, NULL
, NULL
)) == NULL
||
5132 gda_data_model_get_n_rows (data
) <= 0 )
5134 gda_command_free (command
);
5136 g_free (file_escaped
);
5140 gda_command_free (command
);
5142 g_free (file_escaped
);
5143 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5148 * Filepath: full local file path, e.g. /home/user/foo/file.c
5150 SymbolDBEngineIterator
*
5151 symbol_db_engine_get_file_symbols (SymbolDBEngine
*dbe
,
5152 const gchar
*file_path
, gint sym_info
)
5154 SymbolDBEnginePriv
*priv
;
5156 GdaCommand
*command
;
5161 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5162 g_return_val_if_fail (file_path
!= NULL
, NULL
);
5165 g_return_val_if_fail (priv
->data_source
!= NULL
, NULL
);
5167 /* check for an already flagged sym_info with FILE_PATH. SYMINFO_FILE_PATH on
5168 * sym_info is already contained into the default query infos.
5170 sym_info
= sym_info
& ~SYMINFO_FILE_PATH
;
5172 /* info_data contains the stuff after SELECT and befor FROM */
5173 info_data
= g_string_new ("");
5175 /* join_data contains the optionals joins to do to retrieve new data on other
5178 join_data
= g_string_new ("");
5180 /* fill info_data and join data with optional sql */
5181 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
5183 /* rember to do a file_path + strlen(priv->data_source): a project relative
5186 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5187 "symbol.file_position, "
5188 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5189 "JOIN file ON symbol.file_defined_id = file.file_id "
5190 "%s WHERE file.file_path = \"%s\"", info_data
->str
, join_data
->str
,
5191 file_path
+ strlen(priv
->data_source
));
5193 DEBUG_PRINT ("DYNAMIC query [file symbols] is %s", query_str
);
5194 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
5195 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
5197 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
5198 command
, NULL
, NULL
)) == NULL
||
5199 gda_data_model_get_n_rows (data
) <= 0 )
5201 gda_command_free (command
);
5206 gda_command_free (command
);
5208 g_string_free (info_data
, FALSE
);
5209 g_string_free (join_data
, FALSE
);
5211 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5215 SymbolDBEngineIterator
*
5216 symbol_db_engine_get_symbol_info_by_id (SymbolDBEngine
*dbe
,
5217 gint sym_id
, gint sym_info
)
5219 SymbolDBEnginePriv
*priv
;
5221 GdaCommand
*command
;
5226 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5229 /* info_data contains the stuff after SELECT and befor FROM */
5230 info_data
= g_string_new ("");
5232 /* join_data contains the optionals joins to do to retrieve new data on other
5235 join_data
= g_string_new ("");
5237 /* fill info_data and join data with optional sql */
5238 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
5240 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5241 "symbol.file_position, "
5242 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5243 "%s WHERE symbol.symbol_id = %d", info_data
->str
, join_data
->str
,
5246 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
5247 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
5248 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
5250 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
5251 command
, NULL
, NULL
)) == NULL
||
5252 gda_data_model_get_n_rows (data
) <= 0 )
5254 gda_command_free (command
);
5259 gda_command_free (command
);
5261 g_string_free (info_data
, FALSE
);
5262 g_string_free (join_data
, FALSE
);
5264 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5268 /* user must free the returned value */
5270 symbol_db_engine_get_full_local_path (SymbolDBEngine
*dbe
, const gchar
* file
)
5272 SymbolDBEnginePriv
*priv
;
5275 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5278 /* DEBUG_PRINT ("joining %s with %s", priv->data_source, file);*/
5279 full_path
= g_strdup_printf ("%s%s", priv
->data_source
, file
);
5284 SymbolDBEngineIterator
*
5285 symbol_db_engine_find_symbol_by_name_pattern (SymbolDBEngine
*dbe
,
5286 const gchar
*name
, gint sym_info
)
5288 SymbolDBEnginePriv
*priv
;
5290 GdaCommand
*command
;
5295 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5298 /* info_data contains the stuff after SELECT and befor FROM */
5299 info_data
= g_string_new ("");
5301 /* join_data contains the optionals joins to do to retrieve new data on other
5304 join_data
= g_string_new ("");
5306 /* fill info_data and join data with optional sql */
5307 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
5309 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5310 "symbol.file_position, "
5311 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5312 "%s WHERE symbol.name LIKE \"%s%%\"", info_data
->str
, join_data
->str
,
5315 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
5316 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
5317 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
5319 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
5320 command
, NULL
, NULL
)) == NULL
||
5321 gda_data_model_get_n_rows (data
) <= 0 )
5323 gda_command_free (command
);
5328 gda_command_free (command
);
5330 g_string_free (info_data
, FALSE
);
5331 g_string_free (join_data
, FALSE
);
5333 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5336 /* No iterator for now. We need the quickest query possible. */
5338 symbol_db_engine_get_parent_scope_id_by_symbol_id (SymbolDBEngine
*dbe
,
5339 gint scoped_symbol_id
)
5342 select * from symbol where scope_definition_id = (
5343 select scope_id from symbol where symbol_id = 26
5347 /* again we're without prepared queries support from libgda... hope
5348 * you guys implement that asap..!
5350 SymbolDBEnginePriv
*priv
;
5352 GdaCommand
*command
;
5354 const GValue
* value
;
5356 g_return_val_if_fail (dbe
!= NULL
, -1);
5359 query_str
= g_strdup_printf ("SELECT symbol.symbol_id FROM symbol "
5360 "WHERE symbol.scope_definition_id = ( "
5361 "SELECT symbol.scope_id FROM symbol WHERE symbol.symbol_id = '%d')",
5364 DEBUG_PRINT ("symbol_db_engine_get_parent_scope_id_by_symbol_id() query is %s",
5366 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
5367 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
5369 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
5370 command
, NULL
, NULL
)) == NULL
||
5371 gda_data_model_get_n_rows (data
) <= 0 )
5373 gda_command_free (command
);
5375 DEBUG_PRINT ("BAILING OUT");
5379 gda_command_free (command
);
5382 value
= gda_data_model_get_value_at (data
, 0, 0);
5383 gint res
= value
!= NULL
&& G_VALUE_HOLDS_INT (value
)
5384 ? g_value_get_int (value
) : -1;
5385 g_object_unref (data
);