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"
130 #define THREADS_MONITOR_LAUNCH_DELAY 200
131 #define THREADS_MAX_CONCURRENT 15
132 #define TRIGGER_SIGNALS_DELAY 500
133 #define TRIGGER_MAX_CLOSURE_RETRIES 10
134 #define THREAD_MAX_CLOSURE_RETRIES 20
138 DO_UPDATE_SYMS_AND_EXIT
,
140 DONT_UPDATE_SYMS_AND_EXIT
,
141 DONT_FAKE_UPDATE_SYMS
,
142 END_UPDATE_GROUP_SYMS
147 PREP_QUERY_WORKSPACE_NEW
= 0,
148 PREP_QUERY_GET_WORKSPACE_ID_BY_UNIQUE_NAME
,
149 PREP_QUERY_PROJECT_NEW
,
150 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME
,
151 PREP_QUERY_UPDATE_PROJECT_ANALIZE_TIME
,
153 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME
,
154 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_NAME
,
155 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_ID
,
156 PREP_QUERY_UPDATE_FILE_ANALIZE_TIME
,
157 PREP_QUERY_LANGUAGE_NEW
,
158 PREP_QUERY_GET_LANGUAGE_ID_BY_UNIQUE_NAME
,
159 PREP_QUERY_SYM_TYPE_NEW
,
160 PREP_QUERY_GET_SYM_TYPE_ID
,
161 PREP_QUERY_SYM_KIND_NEW
,
162 PREP_QUERY_GET_SYM_KIND_BY_UNIQUE_NAME
,
163 PREP_QUERY_SYM_ACCESS_NEW
,
164 PREP_QUERY_GET_SYM_ACCESS_BY_UNIQUE_NAME
,
165 PREP_QUERY_SYM_IMPLEMENTATION_NEW
,
166 PREP_QUERY_GET_SYM_IMPLEMENTATION_BY_UNIQUE_NAME
,
167 PREP_QUERY_HERITAGE_NEW
,
168 PREP_QUERY_SCOPE_NEW
,
169 PREP_QUERY_GET_SCOPE_ID
,
170 PREP_QUERY_TMP_HERITAGE_NEW
,
171 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE
,
172 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE_WITH_INHERITS
,
173 PREP_QUERY_TMP_HERITAGE_DELETE_ALL
,
174 PREP_QUERY_SYMBOL_NEW
,
175 PREP_QUERY_GET_SYMBOL_SCOPE_DEFINITION_ID
,
176 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME
,
177 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME_AND_NAMESPACE
,
178 PREP_QUERY_UPDATE_SYMBOL_SCOPE_ID
,
179 PREP_QUERY_GET_SYMBOL_ID_BY_UNIQUE_INDEX_KEY
,
180 PREP_QUERY_UPDATE_SYMBOL_ALL
,
181 PREP_QUERY_GET_REMOVED_IDS
,
182 PREP_QUERY_TMP_REMOVED_DELETE_ALL
,
187 typedef struct _query_node
196 /* *MUST* respect query_type enum order. */
197 /* FIXME: 'LIMIT' keyword. This can be used to
198 * speed up some select(s). Please upgrade them as soon as the library support
201 static query_node query_list
[PREP_QUERY_COUNT
] = {
202 /* -- workspace -- */
204 PREP_QUERY_WORKSPACE_NEW
,
205 "INSERT INTO workspace (workspace_name, analize_time) "
206 "VALUES (## /* name:'wsname' type:gchararray */,"
207 "datetime ('now', 'localtime'))",
211 PREP_QUERY_GET_WORKSPACE_ID_BY_UNIQUE_NAME
,
212 "SELECT workspace_id FROM workspace WHERE workspace_name = ## /* name:'wsname' "
213 "type:gchararray */",
218 PREP_QUERY_PROJECT_NEW
,
219 "INSERT INTO project (project_name, wrkspace_id, analize_time) "
220 "VALUES (## /* name:'prjname' type:gchararray */,"
221 "## /* name:'wsid' type:gint */, datetime ('now', 'localtime'))",
225 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME
,
226 "SELECT project_id FROM project WHERE project_name = ## /* name:'prjname' "
227 "type:gchararray */",
231 PREP_QUERY_UPDATE_PROJECT_ANALIZE_TIME
,
232 "UPDATE project SET analize_time = datetime('now', 'localtime') WHERE "
233 "project_name = ## /* name:'prjname' type:gchararray */",
239 "INSERT INTO file (file_path, prj_id, lang_id, analize_time) VALUES ("
240 "## /* name:'filepath' type:gchararray */, ## /* name:'prjid' "
241 "type:gint */, ## /* name:'langid' type:gint */, "
242 "datetime ('now', 'localtime'))",
246 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME
,
247 "SELECT file_id FROM file WHERE file_path = ## /* name:'filepath' "
248 "type:gchararray */",
252 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_NAME
,
253 "SELECT * FROM file WHERE prj_id = (SELECT project_id FROM project "
254 "WHERE project_name = ## /* name:'prjname' type:gchararray */)",
258 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_ID
,
259 "SELECT * FROM file WHERE prj_id = ## /* name:'prjid' type:gint */",
261 "SELECT * FROM file JOIN project on project_id = prj_id WHERE "\
262 "project.name = ## / * name:'prjname' type:gchararray * /",
267 PREP_QUERY_UPDATE_FILE_ANALIZE_TIME
,
268 "UPDATE file SET analize_time = datetime('now', 'localtime') WHERE "
269 "file_path = ## /* name:'filepath' type:gchararray */",
273 PREP_QUERY_LANGUAGE_NEW
,
274 "INSERT INTO language (language_name) VALUES (## /* name:'langname' "
275 "type:gchararray */)",
279 PREP_QUERY_GET_LANGUAGE_ID_BY_UNIQUE_NAME
,
280 "SELECT language_id FROM language WHERE language_name = ## /* name:'langname' "
281 "type:gchararray */",
286 PREP_QUERY_SYM_TYPE_NEW
,
287 "INSERT INTO sym_type (type, type_name) VALUES (## /* name:'type' "
288 "type:gchararray */, ## /* name:'typename' type:gchararray */)",
292 PREP_QUERY_GET_SYM_TYPE_ID
,
293 "SELECT type_id FROM sym_type WHERE type = ## /* name:'type' "
294 "type:gchararray */ AND type_name = ## /* name:'typename' "
295 "type:gchararray */",
300 PREP_QUERY_SYM_KIND_NEW
,
301 "INSERT INTO sym_kind (kind_name) VALUES(## /* name:'kindname' "
302 "type:gchararray */)",
306 PREP_QUERY_GET_SYM_KIND_BY_UNIQUE_NAME
,
307 "SELECT sym_kind_id FROM sym_kind WHERE kind_name = ## /* "
308 "name:'kindname' type:gchararray */",
311 /* -- sym access -- */
313 PREP_QUERY_SYM_ACCESS_NEW
,
314 "INSERT INTO sym_access (access_name) VALUES(## /* name:'accesskind' "
315 "type:gchararray */)",
319 PREP_QUERY_GET_SYM_ACCESS_BY_UNIQUE_NAME
,
320 "SELECT access_kind_id FROM sym_access WHERE access_name = ## /* "
321 "name:'accesskind' type:gchararray */",
324 /* -- sym implementation -- */
326 PREP_QUERY_SYM_IMPLEMENTATION_NEW
,
327 "INSERT INTO sym_implementation (implementation_name) VALUES(## /* name:'implekind' "
328 "type:gchararray */)",
332 PREP_QUERY_GET_SYM_IMPLEMENTATION_BY_UNIQUE_NAME
,
333 "SELECT sym_impl_id FROM sym_implementation WHERE kind = ## /* "
334 "name:'implekind' type:gchararray */",
339 PREP_QUERY_HERITAGE_NEW
,
340 "INSERT INTO heritage (symbol_id_base, symbol_id_derived) VALUES(## /* "
341 "name:'symbase' type:gint */, ## /* name:'symderived' type:gint */)",
346 PREP_QUERY_SCOPE_NEW
,
347 "INSERT INTO scope (scope_name, type_id) VALUES(## /* name:'scope' "
348 "type:gchararray */, ## /* name:'typeid' type:gint */)",
352 PREP_QUERY_GET_SCOPE_ID
,
353 "SELECT scope_id FROM scope WHERE scope_name = ## /* name:'scope' "
354 "type:gchararray */ AND type_id = ## /* name:'typeid' type:gint */",
357 /* -- tmp heritage -- */
359 PREP_QUERY_TMP_HERITAGE_NEW
,
360 "INSERT INTO __tmp_heritage_scope (symbol_referer_id, field_inherits, "
361 "field_struct, field_typeref, field_enum, field_union, "
362 "field_class, field_namespace) VALUES (## /* name:'symreferid' "
363 "type:gint */, ## /* name:'finherits' type:gchararray */, ## /* "
364 "name:'fstruct' type:gchararray */, ## /* name:'ftyperef' "
365 "type:gchararray */, ## /* name:'fenum' type:gchararray */, ## /* "
366 "name:'funion' type:gchararray */, ## /* name:'fclass' type:gchararray "
367 "*/, ## /* name:'fnamespace' type:gchararray */)",
371 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE
,
372 "SELECT * FROM __tmp_heritage_scope",
376 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE_WITH_INHERITS
,
377 "SELECT * FROM __tmp_heritage_scope WHERE field_inherits != ''",
381 PREP_QUERY_TMP_HERITAGE_DELETE_ALL
,
382 "DELETE FROM __tmp_heritage_scope",
387 PREP_QUERY_SYMBOL_NEW
,
388 "INSERT INTO symbol (file_defined_id, name, file_position, "
389 "is_file_scope, signature, scope_definition_id, scope_id, type_id, "
390 "kind_id, access_kind_id, implementation_kind_id, update_flag) VALUES("
391 "## /* name:'filedefid' type:gint */, ## /* name:'name' "
392 "type:gchararray */, ## /* name:'fileposition' type:gint */, ## /* "
393 "name:'isfilescope' type:gint */, ## /* name:'signature' "
394 "type:gchararray */,## /* name:'scopedefinitionid' type:gint */, ## "
395 "/* name:'scopeid' type:gint */,## /* name:'typeid' type:gint */, ## "
396 "/* name:'kindid' type:gint */,## /* name:'accesskindid' type:gint */, "
397 "## /* name:'implementationkindid' type:gint */, ## /* "
398 "name:'updateflag' type:gint */)",
402 PREP_QUERY_GET_SYMBOL_SCOPE_DEFINITION_ID
,
403 "SELECT scope_definition_id FROM symbol JOIN sym_type ON symbol.type_id "
404 "= sym_type.type_id WHERE sym_type.type = ## /* name:'tokenname' "
405 "type:gchararray */ AND sym_type.type_name = ## /* name:'objectname' "
406 "type:gchararray */ LIMIT 1",
410 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME
,
411 "SELECT symbol_id FROM symbol JOIN sym_type ON symbol.type_id = "
412 "sym_type.type_id WHERE scope_id=0 AND sym_type.type='class' AND "
413 "name = ## /* name:'klassname' type:gchararray */",
417 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME_AND_NAMESPACE
,
418 "SELECT symbol_id FROM symbol JOIN scope ON symbol.scope_id = "
419 "scope.scope_id JOIN sym_type ON scope.type_id = sym_type.type_id "
420 "WHERE symbol.name = /* name:'klassname' type:gchararray */ AND "
421 "scope.scope_name = /* name:'namespacename' type:gchararray */ AND "
422 "sym_type.type='namespace'",
426 PREP_QUERY_UPDATE_SYMBOL_SCOPE_ID
,
427 "UPDATE symbol SET scope_id = ## /* name:'scopeid' type:gint */ "
428 "WHERE symbol_id = ## /* name:'symbolid' type:gint */",
432 PREP_QUERY_GET_SYMBOL_ID_BY_UNIQUE_INDEX_KEY
,
433 "SELECT symbol_id FROM symbol WHERE name = ## /* name:'symname' "
434 "type:gchararray */ AND file_defined_id = ## /* name:'filedefid' "
435 "type:gint */ AND type_id = ## /* name:'typeid' type:gint */",
439 PREP_QUERY_UPDATE_SYMBOL_ALL
,
440 "UPDATE symbol SET is_file_scope = ## /* name:'isfilescope' type:gint "
441 "*/, file_position = ## /* name:'fileposition' type:gint */, "
442 "signature = ## /* name:'signature' type:gchararray */, "
443 "scope_definition_id = ## /* name:'scopedefinitionid' type:gint */, "
444 "scope_id = ## /* name:'scopeid' type:gint */, kind_id = "
445 "## /* name:'kindid' type:gint */, access_kind_id = ## /* name:"
446 "'accesskindid' type:gint */, implementation_kind_id = ## /* name:"
447 "'implementationkindid' type:gint */, update_flag = ## /* name:"
448 "'updateflag' type:gint */ WHERE symbol_id = ## /* name:'symbolid' type:"
452 /* -- tmp_removed -- */
454 PREP_QUERY_GET_REMOVED_IDS
,
455 "SELECT symbol_removed_id FROM __tmp_removed",
459 PREP_QUERY_TMP_REMOVED_DELETE_ALL
,
460 "DELETE FROM __tmp_removed",
465 typedef void (SymbolDBEngineCallback
) (SymbolDBEngine
* dbe
,
470 SINGLE_FILE_SCAN_END
,
474 SYMBOL_SCOPE_UPDATED
,
479 static unsigned int signals
[LAST_SIGNAL
] = { 0 };
481 struct _SymbolDBEnginePriv
483 GdaConnection
*db_connection
;
484 GdaClient
*gda_client
;
489 GAsyncQueue
*scan_queue
;
490 GAsyncQueue
*updated_symbols_id
;
491 GAsyncQueue
*inserted_symbols_id
;
493 gchar
*shared_mem_str
;
494 FILE *shared_mem_file
;
496 AnjutaLauncher
*ctags_launcher
;
497 gboolean scanning_status
;
498 gboolean force_sym_update
;
501 GAsyncQueue
* signals_queue
;
504 gboolean thread_status
;
505 gint concurrent_threads
;
507 gint thread_monitor_handler
;
508 gint timeout_trigger_handler
;
510 gint trigger_closure_retries
;
511 gint thread_closure_retries
;
514 static GObjectClass
*parent_class
= NULL
;
517 typedef struct _ThreadDataOutput
{
523 static void sdb_engine_second_pass_do (SymbolDBEngine
* dbe
);
525 sdb_engine_add_new_symbol (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
,
526 const gchar
* base_prj_path
, const gchar
* fake_file
,
527 gboolean sym_update
);
531 * Malerba here http://bugzilla.gnome.org/show_bug.cgi?id=488860 says that
532 * GdaQueries can be seen by a provider as prepared queries. I'm not 100% sure
533 * about this but anyway give it a try.
536 sdb_engine_execute_non_select_sql (SymbolDBEngine
* dbe
, const gchar
* buffer
)
538 SymbolDBEnginePriv
*priv
;
544 query
= gda_query_new_from_sql (NULL
, buffer
, NULL
);
545 obj
= gda_query_execute (query
, NULL
, FALSE
, NULL
);
549 g_object_unref (obj
);
554 g_object_unref (query
);
559 * User must care to g_object_unref () the returned data_model.
561 static GdaDataModel
*
562 sdb_engine_execute_select_sql (SymbolDBEngine
* dbe
, const gchar
* buffer
)
564 SymbolDBEnginePriv
*priv
;
567 GError
*error
= NULL
;
571 query
= gda_query_new_from_sql (NULL
, buffer
, &error
);
574 g_print ("Parser ERROR: %s\n", error->message);
576 obj
= gda_query_execute (query
, NULL
, FALSE
, NULL
);
581 g_object_unref (query
);
584 if (GDA_DATA_MODEL (obj
) == FALSE
)
586 DEBUG_PRINT ("sdb_engine_execute_select_sql (): returning NULL");
588 g_object_unref (obj
);
592 return GDA_DATA_MODEL (obj
);
597 * Will test the opened project within the dbe plugin and the passed one.
600 symbol_db_engine_is_project_opened (SymbolDBEngine
*dbe
, const gchar
* project_name
)
602 SymbolDBEnginePriv
*priv
;
604 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
607 if (priv
->project_name
== NULL
)
610 return strcmp (project_name
, priv
->project_name
) == 0 ? TRUE
: FALSE
;
615 * Use a proxy to return an already present or a fresh new prepared query
616 * from static 'query_list'. We should perform actions in the fastest way, because
617 * these queries are time-critical.
619 static inline const GdaQuery
*
620 sdb_engine_get_query_by_id (SymbolDBEngine
* dbe
, query_type query_id
)
623 SymbolDBEnginePriv
*priv
;
627 /* no way: if connection is NULL we will break here. There must be
628 * a connection established to db before using this function */
629 g_return_val_if_fail (priv
->db_connection
!= NULL
, NULL
);
631 node
= &query_list
[query_id
];
633 if (node
->query
== NULL
)
635 DEBUG_PRINT ("generating new query.... %d", query_id
);
636 /* create a new GdaQuery */
638 gda_query_new_from_sql (NULL
, node
->query_str
, NULL
);
645 sdb_engine_get_last_insert_id (SymbolDBEngine
* dbe
)
648 SymbolDBEnginePriv
*priv
;
652 res
= gda_connection_get_last_insert_id (priv
->db_connection
, NULL
);
653 table_id
= atoi (res
);
659 * Clear the static cached queries data. You should call this function when closing/
660 * destroying SymbolDBEngine object.
663 sdb_engine_free_cached_queries (SymbolDBEngine
* dbe
)
667 SymbolDBEnginePriv
*priv
;
671 for (i
= 0; i
< PREP_QUERY_COUNT
; i
++)
673 node
= &query_list
[i
];
675 if (node
->query
!= NULL
)
677 g_object_unref ((gpointer
) node
->query
);
684 sdb_engine_disconnect_from_db (SymbolDBEngine
* dbe
)
686 SymbolDBEnginePriv
*priv
;
688 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
691 if (priv
->gda_client
)
693 gda_client_close_all_connections (priv
->gda_client
);
694 g_object_unref (priv
->gda_client
);
696 priv
->gda_client
= NULL
;
697 priv
->db_connection
= NULL
;
699 g_free (priv
->data_source
);
700 priv
->data_source
= NULL
;
702 g_free (priv
->dsn_name
);
703 priv
->dsn_name
= NULL
;
708 static GTimer
*sym_timer_DEBUG
= NULL
;
709 static gint files_scanned_DEBUG
= 0;
712 * If base_prj_path != NULL then fake_file will not be parsed. Else
713 * if fake_file is != NULL we claim and assert that tags contents which are
714 * scanned belong to the fake_file in the project.
715 * More: the fake_file refers to just one single file and cannot be used
716 * for multiple fake_files.
719 sdb_engine_populate_db_by_tags (SymbolDBEngine
* dbe
, FILE* fd
,
720 gchar
* base_prj_path
, gchar
* fake_file_on_db
,
721 gboolean force_sym_update
)
724 tagFileInfo tag_file_info
;
728 SymbolDBEnginePriv
*priv
;
730 g_return_if_fail (dbe
!= NULL
);
734 g_return_if_fail (priv
->db_connection
!= NULL
);
735 g_return_if_fail (fd
!= NULL
);
737 if (priv
->updated_symbols_id
== NULL
)
738 priv
->updated_symbols_id
= g_async_queue_new ();
740 if (priv
->inserted_symbols_id
== NULL
)
741 priv
->inserted_symbols_id
= g_async_queue_new ();
743 DEBUG_PRINT ("sdb_engine_populate_db_by_tags ()");
744 if ((tag_file
= tagsOpen_1 (fd
, &tag_file_info
)) == NULL
)
746 g_warning ("error in opening ctags file");
749 gda_connection_begin_transaction (priv
->db_connection
, NULL
,
750 GDA_TRANSACTION_ISOLATION_READ_UNCOMMITTED
,
753 if (sym_timer_DEBUG
== NULL
)
754 sym_timer_DEBUG
= g_timer_new ();
756 g_timer_reset (sym_timer_DEBUG
);
757 gint tags_total_DEBUG
= 0;
759 while (tagsNext (tag_file
, &tag_entry
) != TagFailure
)
761 sdb_engine_add_new_symbol (dbe
, &tag_entry
, fake_file_on_db
== NULL
?
762 base_prj_path
: NULL
, fake_file_on_db
,
768 gdouble elapsed_DEBUG
= g_timer_elapsed (sym_timer_DEBUG
, NULL
);
769 DEBUG_PRINT ("elapsed: %f for (%d) [%f per symbol]", elapsed_DEBUG
,
770 tags_total_DEBUG
, elapsed_DEBUG
/ tags_total_DEBUG
);
773 if (files_scanned_DEBUG
++ > 50)
775 DEBUG_PRINT ("analyzing...");
776 command
= gda_command_new ("ANALYZE", GDA_COMMAND_TYPE_SQL
,
777 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
778 gda_connection_execute_non_select_command (priv
->db_connection
,
779 command
, NULL
, NULL
);
780 gda_command_free (command
);
782 files_scanned_DEBUG
= 0;
785 DEBUG_PRINT ("EMITTING single-file-scan-end");
786 /* notify listeners that another file has been scanned */
787 g_async_queue_push (priv
->signals_queue
, (gpointer
)(SINGLE_FILE_SCAN_END
+1));
789 gda_connection_commit_transaction (priv
->db_connection
, NULL
, NULL
);
793 sdb_engine_ctags_output_thread (gpointer data
)
795 ThreadDataOutput
*output
;
797 gchar
*chars
, *chars_ptr
;
798 gint remaining_chars
;
800 SymbolDBEnginePriv
*priv
;
803 output
= (ThreadDataOutput
*)data
;
804 dbe
= output
->user_data
;
805 chars
= chars_ptr
= output
->chars
;
807 g_return_val_if_fail (dbe
!= NULL
, (gpointer
)-1);
808 g_return_val_if_fail (chars_ptr
!= NULL
, (gpointer
)-1);
814 g_mutex_lock (priv
->mutex
);
815 priv
->thread_status
= TRUE
;
817 remaining_chars
= len_chars
= strlen (chars_ptr
);
818 len_marker
= strlen (CTAGS_MARKER
);
820 if ( len_chars
>= len_marker
)
822 gchar
*marker_ptr
= NULL
;
823 gint tmp_str_length
= 0;
825 /* is it an end file marker? */
826 marker_ptr
= strstr (chars_ptr
, CTAGS_MARKER
);
829 if (marker_ptr
!= NULL
)
833 DEBUG_PRINT ("found marker!");
835 /* set the length of the string parsed */
836 tmp_str_length
= marker_ptr
- chars_ptr
;
838 /*DEBUG_PRINT ("program output [new version]: ==>%s<==", chars_ptr);*/
839 /* write to shm_file all the chars_ptr received without the marker ones */
840 fwrite (chars_ptr
, sizeof(gchar
), tmp_str_length
, priv
->shared_mem_file
);
842 chars_ptr
= marker_ptr
+ len_marker
;
843 remaining_chars
-= (tmp_str_length
+ len_marker
);
844 fflush (priv
->shared_mem_file
);
846 /* get the scan flag from the queue. We need it to know whether
847 * an update of symbols must be done or not */
848 scan_flag
= (int)g_async_queue_try_pop (priv
->scan_queue
);
849 real_file
= g_async_queue_try_pop (priv
->scan_queue
);
851 /* and now call the populating function */
852 if (scan_flag
== DO_UPDATE_SYMS
||
853 scan_flag
== DO_UPDATE_SYMS_AND_EXIT
)
855 sdb_engine_populate_db_by_tags (dbe
, priv
->shared_mem_file
,
857 (int)real_file
== DONT_FAKE_UPDATE_SYMS
? NULL
: real_file
,
862 sdb_engine_populate_db_by_tags (dbe
, priv
->shared_mem_file
,
864 (int)real_file
== DONT_FAKE_UPDATE_SYMS
? NULL
: real_file
,
868 /* don't forget to free the real_file, if it's a char */
869 if ((int)real_file
!= DONT_FAKE_UPDATE_SYMS
)
872 /* check also if, together with an end file marker, we have an
873 * end group-of-files end marker.
875 if (scan_flag
== DO_UPDATE_SYMS_AND_EXIT
||
876 scan_flag
== DONT_UPDATE_SYMS_AND_EXIT
)
881 /* proceed with second passes */
882 DEBUG_PRINT ("FOUND end-of-group-files marker.\n"
883 "go on with sdb_engine_second_pass_do ()");
885 chars_ptr
+= len_marker
;
886 remaining_chars
-= len_marker
;
888 /* will emit symbol_scope_updated */
889 sdb_engine_second_pass_do (dbe
);
891 /* Here we are. It's the right time to notify the listeners
892 * about out fresh new inserted/updated symbols...
893 * Go on by emitting them.
895 while ((tmp_inserted
= (int)
896 g_async_queue_try_pop (priv
->inserted_symbols_id
)) > 0)
898 DEBUG_PRINT ("EMITTING symbol-inserted %d", tmp_inserted
);
899 /* we must be sure to insert both signals at once */
900 g_async_queue_lock (priv
->signals_queue
);
902 /* the +1 is because asyn_queue doesn't want NULL values */
903 g_async_queue_push_unlocked (priv
->signals_queue
,
904 (gpointer
)(SYMBOL_INSERTED
+ 1));
905 g_async_queue_push_unlocked (priv
->signals_queue
,
906 (gpointer
) tmp_inserted
);
907 g_async_queue_unlock (priv
->signals_queue
);
910 while ((tmp_updated
= (int)
911 g_async_queue_try_pop (priv
->updated_symbols_id
)) > 0)
913 DEBUG_PRINT ("EMITTING symbol-updated");
914 g_async_queue_lock (priv
->signals_queue
);
915 g_async_queue_push_unlocked (priv
->signals_queue
, (gpointer
)
916 (SYMBOL_UPDATED
+ 1));
917 g_async_queue_push_unlocked (priv
->signals_queue
,
918 (gpointer
) tmp_updated
);
919 g_async_queue_unlock (priv
->signals_queue
);
923 /* emit signal. The end of files-group can be cannot be
924 * determined by the caller. This is the only way.
926 DEBUG_PRINT ("EMITTING scan-end");
927 g_async_queue_push (priv
->signals_queue
, (gpointer
)(SCAN_END
+ 1));
928 DEBUG_PRINT ("queue length = %d",
929 g_async_queue_length (priv
->signals_queue
));
932 /* truncate the file to 0 length */
933 ftruncate (priv
->shared_mem_fd
, 0);
937 /* marker_ptr is NULL here. We should then exit the loop. */
938 /* write to shm_file all the chars received */
939 fwrite (chars_ptr
, sizeof(gchar
), remaining_chars
,
940 priv
->shared_mem_file
);
942 fflush (priv
->shared_mem_file
);
946 /* found out a new marker */
947 marker_ptr
= strstr (marker_ptr
+ len_marker
, CTAGS_MARKER
);
948 } while (remaining_chars
+ len_marker
< len_chars
);
952 DEBUG_PRINT ("no len_chars > len_marker");
955 priv
->thread_status
= FALSE
;
956 priv
->concurrent_threads
--;
958 g_mutex_unlock (priv
->mutex
);
968 sdb_engine_timeout_trigger_signals (gpointer user_data
)
970 SymbolDBEngine
*dbe
= (SymbolDBEngine
*) user_data
;
971 SymbolDBEnginePriv
*priv
;
973 g_return_val_if_fail (user_data
!= NULL
, FALSE
);
977 DEBUG_PRINT ("signals trigger");
978 if (g_async_queue_length (priv
->signals_queue
) > 0)
981 gpointer sign
= NULL
;
984 while ((sign
= g_async_queue_try_pop (priv
->signals_queue
)) != NULL
) {
987 return g_async_queue_length (priv
->signals_queue
) > 0 ? TRUE
: FALSE
;
990 real_signal
= (gint
)sign
- 1;
992 switch (real_signal
) {
993 case SINGLE_FILE_SCAN_END
:
994 g_signal_emit (dbe
, signals
[SINGLE_FILE_SCAN_END
], 0);
998 g_signal_emit (dbe
, signals
[SCAN_END
], 0);
1001 case SYMBOL_INSERTED
:
1002 tmp
= g_async_queue_try_pop (priv
->signals_queue
);
1003 g_signal_emit (dbe
, signals
[SYMBOL_INSERTED
], 0, tmp
);
1006 case SYMBOL_UPDATED
:
1007 tmp
= g_async_queue_try_pop (priv
->signals_queue
);
1008 g_signal_emit (dbe
, signals
[SYMBOL_UPDATED
], 0, tmp
);
1011 case SYMBOL_SCOPE_UPDATED
:
1012 tmp
= g_async_queue_try_pop (priv
->signals_queue
);
1013 g_signal_emit (dbe
, signals
[SYMBOL_SCOPE_UPDATED
], 0, tmp
);
1016 case SYMBOL_REMOVED
:
1017 tmp
= g_async_queue_try_pop (priv
->signals_queue
);
1018 g_signal_emit (dbe
, signals
[SYMBOL_REMOVED
], 0, tmp
);
1022 /* reset to 0 the retries */
1023 priv
->trigger_closure_retries
= 0;
1026 priv
->trigger_closure_retries
++;
1029 if (priv
->trigger_closure_retries
> TRIGGER_MAX_CLOSURE_RETRIES
&&
1030 g_queue_get_length (priv
->thread_list
) <= 0)
1032 DEBUG_PRINT ("removing trigger");
1033 /* remove the trigger coz we don't need it anymore... */
1034 g_source_remove (priv
->timeout_trigger_handler
);
1035 priv
->timeout_trigger_handler
= 0;
1042 sdb_engine_thread_monitor (gpointer data
)
1045 SymbolDBEngine
*dbe
= (SymbolDBEngine
*) data
;
1046 SymbolDBEnginePriv
*priv
;
1048 g_return_val_if_fail (data
!= NULL
, FALSE
);
1051 DEBUG_PRINT ("thread monitor");
1053 if (priv
->concurrent_threads
> THREADS_MAX_CONCURRENT
) {
1054 /* monitor acted here. There plenty threads already working. */
1058 output
= g_queue_pop_head (priv
->thread_list
);
1062 priv
->concurrent_threads
++;
1063 g_thread_create ((GThreadFunc
)sdb_engine_ctags_output_thread
, output
,
1065 priv
->thread_closure_retries
= 0;
1069 priv
->thread_closure_retries
++;
1072 if (priv
->thread_closure_retries
> THREAD_MAX_CLOSURE_RETRIES
)
1074 DEBUG_PRINT ("removing thread monitor");
1075 /* remove the thread monitor */
1076 g_source_remove (priv
->thread_monitor_handler
);
1077 priv
->thread_monitor_handler
= 0;
1080 /* recall this monitor */
1085 sdb_engine_ctags_output_callback_1 (AnjutaLauncher
* launcher
,
1086 AnjutaLauncherOutputType output_type
,
1087 const gchar
* chars
, gpointer user_data
)
1089 ThreadDataOutput
*output
;
1090 SymbolDBEngine
*dbe
= (SymbolDBEngine
*) user_data
;
1091 SymbolDBEnginePriv
*priv
;
1093 g_return_if_fail (user_data
!= NULL
);
1097 output
= g_new0 (ThreadDataOutput
, 1);
1098 output
->chars
= g_strdup (chars
);
1099 output
->user_data
= user_data
;
1101 if (priv
->thread_list
== NULL
)
1102 priv
->thread_list
= g_queue_new ();
1104 g_queue_push_tail (priv
->thread_list
, output
);
1106 /* thread monitor */
1107 if (priv
->thread_monitor_handler
<= 0)
1109 priv
->thread_monitor_handler
=
1110 g_timeout_add (THREADS_MONITOR_LAUNCH_DELAY
,
1111 sdb_engine_thread_monitor
, user_data
);
1112 priv
->thread_closure_retries
= 0;
1115 /* signals monitor */
1116 if (priv
->timeout_trigger_handler
<= 0)
1118 priv
->timeout_trigger_handler
=
1119 g_timeout_add (TRIGGER_SIGNALS_DELAY
,
1120 sdb_engine_timeout_trigger_signals
, user_data
);
1121 priv
->trigger_closure_retries
= 0;
1126 on_scan_files_end_1 (AnjutaLauncher
* launcher
, int child_pid
,
1127 int exit_status
, gulong time_taken_in_seconds
,
1130 DEBUG_PRINT ("ctags ended");
1133 /* Scans with ctags and produce an output 'tags' file [shared memory file]
1134 * containing language symbols. This function will call ctags
1135 * executale and then sdb_engine_populate_db_by_tags () when it'll detect some
1137 * Please note the files_list/real_files_list parameter:
1138 * this version of sdb_engine_scan_files_1 () let you scan for text buffer(s) that
1139 * will be claimed as buffers for the real files.
1140 * 1. simple mode: files_list represents the real files on disk and so we don't
1141 * need real_files_list, which will be NULL.
1142 * 2. advanced mode: files_list represents temporary flushing of buffers on disk, i.e.
1143 * /tmp/anjuta_XYZ.cxx. real_files_list is the representation of those files on
1144 * database. On the above example we can have anjuta_XYZ.cxx mapped as /src/main.c
1145 * on db. In this mode files_list and real_files_list must have the same size.
1148 /* server mode version */
1150 sdb_engine_scan_files_1 (SymbolDBEngine
* dbe
, const GPtrArray
* files_list
,
1151 const GPtrArray
*real_files_list
, gboolean symbols_update
)
1153 SymbolDBEnginePriv
*priv
;
1156 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
1157 g_return_val_if_fail (files_list
!= NULL
, FALSE
);
1159 if (files_list
->len
== 0)
1162 /* start process in server mode */
1165 if (real_files_list
!= NULL
&& (files_list
->len
!= real_files_list
->len
))
1167 g_warning ("no matched size between real_files_list and files_list");
1171 /* if ctags_launcher isn't initialized, then do it now. */
1172 if (priv
->ctags_launcher
== NULL
)
1176 DEBUG_PRINT ("creating anjuta_launcher");
1177 priv
->ctags_launcher
= anjuta_launcher_new ();
1179 g_signal_connect (G_OBJECT (priv
->ctags_launcher
), "child-exited",
1180 G_CALLBACK (on_scan_files_end_1
), NULL
);
1182 exe_string
= g_strdup_printf ("%s --fields=afmiKlnsStz --c++-kinds=+p "
1183 "--filter=yes --filter-terminator='"CTAGS_MARKER
"'",
1186 anjuta_launcher_execute (priv
->ctags_launcher
,
1187 exe_string
, sdb_engine_ctags_output_callback_1
,
1189 g_free (exe_string
);
1192 /* what about the scan_queue? is it initialized? It will contain mainly
1193 * ints that refers to the force_update status.
1195 if (priv
->scan_queue
== NULL
)
1197 priv
->scan_queue
= g_async_queue_new ();
1200 /* create the shared memory file */
1201 if (priv
->shared_mem_file
== 0)
1204 temp_file
= g_strdup_printf ("/anjuta-%d_%ld.tags", getpid (),
1207 priv
->shared_mem_str
= temp_file
;
1209 if ((priv
->shared_mem_fd
=
1210 shm_open (temp_file
, O_CREAT
|O_RDWR
, S_IRUSR
|S_IWUSR
)) < 0)
1212 g_warning ("Error while trying to open a shared memory file. Be"
1213 "sure to have /dev/shm mounted with tmpfs");
1216 priv
->shared_mem_file
= fdopen (priv
->shared_mem_fd
, "a+b");
1217 DEBUG_PRINT ("temp_file %s", temp_file
);
1219 /* no need to free temp_file. It will be freed on plugin finalize */
1222 priv
->scanning_status
= TRUE
;
1224 DEBUG_PRINT ("sdb_engine_scan_files_1 (): PUSHING files_list->len %d to scan",
1226 for (i
= 0; i
< files_list
->len
; i
++)
1228 gchar
*node
= (gchar
*) g_ptr_array_index (files_list
, i
);
1230 if (g_file_test (node
, G_FILE_TEST_EXISTS
) == FALSE
)
1232 g_warning ("File %s not scanned because it does not exist", node
);
1236 DEBUG_PRINT ("sent to stdin %d", i
);
1237 anjuta_launcher_send_stdin (priv
->ctags_launcher
, node
);
1238 anjuta_launcher_send_stdin (priv
->ctags_launcher
, "\n");
1240 if (symbols_update
== TRUE
)
1242 /* will this be the last file in the list? */
1243 if (i
+ 1 >= files_list
->len
)
1246 g_async_queue_push (priv
->scan_queue
, (gpointer
) DO_UPDATE_SYMS_AND_EXIT
);
1250 g_async_queue_push (priv
->scan_queue
, (gpointer
) DO_UPDATE_SYMS
);
1255 if (i
+ 1 >= files_list
->len
)
1258 g_async_queue_push (priv
->scan_queue
, (gpointer
) DONT_UPDATE_SYMS_AND_EXIT
);
1262 g_async_queue_push (priv
->scan_queue
, (gpointer
) DONT_UPDATE_SYMS
);
1266 /* don't forget to add the real_files if the caller provided a list for
1268 if (real_files_list
!= NULL
)
1270 g_async_queue_push (priv
->scan_queue
,
1271 (gpointer
)g_strdup (
1272 g_ptr_array_index (real_files_list
, i
)));
1276 /* else add a DONT_FAKE_UPDATE_SYMS marker, just to notify that this
1277 * is not a fake file scan
1279 g_async_queue_push (priv
->scan_queue
, (gpointer
) DONT_FAKE_UPDATE_SYMS
);
1283 priv
->scanning_status
= FALSE
;
1289 sdb_engine_init (SymbolDBEngine
* object
)
1291 SymbolDBEngine
*sdbe
;
1293 sdbe
= SYMBOL_DB_ENGINE (object
);
1294 sdbe
->priv
= g_new0 (SymbolDBEnginePriv
, 1);
1296 /* initialize some priv data */
1297 sdbe
->priv
->gda_client
= NULL
;
1298 sdbe
->priv
->db_connection
= NULL
;
1299 sdbe
->priv
->dsn_name
= NULL
;
1300 sdbe
->priv
->project_name
= NULL
;
1301 sdbe
->priv
->data_source
= NULL
;
1303 sdbe
->priv
->scan_queue
= NULL
;
1304 sdbe
->priv
->updated_symbols_id
= NULL
;
1305 sdbe
->priv
->inserted_symbols_id
= NULL
;
1306 sdbe
->priv
->shared_mem_file
= NULL
;
1307 sdbe
->priv
->shared_mem_fd
= 0;
1308 sdbe
->priv
->shared_mem_str
= NULL
;
1309 sdbe
->priv
->scanning_status
= FALSE
;
1310 sdbe
->priv
->force_sym_update
= FALSE
;
1312 sdbe
->priv
->mutex
= NULL
;
1313 sdbe
->priv
->signals_queue
= NULL
;
1314 sdbe
->priv
->thread_list
= NULL
;
1315 sdbe
->priv
->thread_status
= FALSE
;
1316 sdbe
->priv
->concurrent_threads
= 0;
1317 sdbe
->priv
->thread_monitor_handler
= 0;
1318 sdbe
->priv
->timeout_trigger_handler
= 0;
1319 sdbe
->priv
->trigger_closure_retries
= 0;
1320 sdbe
->priv
->thread_closure_retries
= 0;
1322 /* Initialize gda library. */
1323 gda_init ("AnjutaGda", NULL
, 0, NULL
);
1325 /* create Anjuta Launcher instance. It will be used for tags parsing. */
1326 sdbe
->priv
->ctags_launcher
= NULL
;
1330 sdb_engine_finalize (GObject
* object
)
1332 SymbolDBEngine
*dbe
;
1333 SymbolDBEnginePriv
*priv
;
1335 dbe
= SYMBOL_DB_ENGINE (object
);
1338 sdb_engine_disconnect_from_db (dbe
);
1339 sdb_engine_free_cached_queries (dbe
);
1341 g_free (priv
->project_name
);
1343 if (priv
->scan_queue
)
1345 g_async_queue_unref (priv
->scan_queue
);
1346 priv
->scan_queue
= NULL
;
1349 if (priv
->updated_symbols_id
)
1351 g_async_queue_unref (priv
->updated_symbols_id
);
1352 priv
->updated_symbols_id
= NULL
;
1356 if (priv
->inserted_symbols_id
)
1358 g_async_queue_unref (priv
->inserted_symbols_id
);
1359 priv
->inserted_symbols_id
= NULL
;
1362 if (priv
->shared_mem_file
)
1364 fclose (priv
->shared_mem_file
);
1365 priv
->shared_mem_file
= NULL
;
1369 if (priv
->shared_mem_str
)
1371 shm_unlink (priv
->shared_mem_str
);
1372 g_free (priv
->shared_mem_str
);
1373 priv
->shared_mem_str
= NULL
;
1376 if (priv
->ctags_launcher
)
1378 anjuta_launcher_signal (priv
->ctags_launcher
, SIGINT
);
1379 g_object_unref (priv
->ctags_launcher
);
1384 g_mutex_lock (priv
->mutex
);
1385 g_mutex_free (priv
->mutex
);
1389 if (priv
->timeout_trigger_handler
>= 0)
1390 g_source_remove (priv
->timeout_trigger_handler
);
1392 if (priv
->thread_monitor_handler
>= 0)
1393 g_source_remove (priv
->thread_monitor_handler
);
1395 g_async_queue_unref (priv
->signals_queue
);
1397 g_queue_free (priv
->thread_list
);
1400 G_OBJECT_CLASS (parent_class
)->finalize (object
);
1404 sdb_engine_class_init (SymbolDBEngineClass
* klass
)
1406 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
1407 parent_class
= G_OBJECT_CLASS (g_type_class_peek_parent (klass
));
1409 object_class
->finalize
= sdb_engine_finalize
;
1411 signals
[SINGLE_FILE_SCAN_END
]
1412 = g_signal_new ("single-file-scan-end",
1413 G_OBJECT_CLASS_TYPE (object_class
),
1415 G_STRUCT_OFFSET (SymbolDBEngineClass
, single_file_scan_end
),
1417 g_cclosure_marshal_VOID__VOID
, G_TYPE_NONE
, 0);
1420 = g_signal_new ("scan-end",
1421 G_OBJECT_CLASS_TYPE (object_class
),
1423 G_STRUCT_OFFSET (SymbolDBEngineClass
, scan_end
),
1425 g_cclosure_marshal_VOID__VOID
, G_TYPE_NONE
, 0);
1427 signals
[SYMBOL_INSERTED
]
1428 = g_signal_new ("symbol-inserted",
1429 G_OBJECT_CLASS_TYPE (object_class
),
1431 G_STRUCT_OFFSET (SymbolDBEngineClass
, symbol_inserted
),
1433 g_cclosure_marshal_VOID__INT
, G_TYPE_NONE
,
1437 signals
[SYMBOL_UPDATED
]
1438 = g_signal_new ("symbol-updated",
1439 G_OBJECT_CLASS_TYPE (object_class
),
1441 G_STRUCT_OFFSET (SymbolDBEngineClass
, symbol_updated
),
1443 g_cclosure_marshal_VOID__INT
, G_TYPE_NONE
,
1447 signals
[SYMBOL_SCOPE_UPDATED
]
1448 = g_signal_new ("symbol-scope-updated",
1449 G_OBJECT_CLASS_TYPE (object_class
),
1451 G_STRUCT_OFFSET (SymbolDBEngineClass
, symbol_scope_updated
),
1453 g_cclosure_marshal_VOID__INT
, G_TYPE_NONE
,
1457 signals
[SYMBOL_REMOVED
]
1458 = g_signal_new ("symbol-removed",
1459 G_OBJECT_CLASS_TYPE (object_class
),
1461 G_STRUCT_OFFSET (SymbolDBEngineClass
, symbol_removed
),
1463 g_cclosure_marshal_VOID__INT
, G_TYPE_NONE
,
1470 sdb_engine_get_type (void)
1472 static GType our_type
= 0;
1476 static const GTypeInfo our_info
= {
1477 sizeof (SymbolDBEngineClass
), /* class_size */
1478 (GBaseInitFunc
) NULL
, /* base_init */
1479 (GBaseFinalizeFunc
) NULL
, /* base_finalize */
1480 (GClassInitFunc
) sdb_engine_class_init
, /* class_init */
1481 (GClassFinalizeFunc
) NULL
, /* class_finalize */
1482 NULL
/* class_data */ ,
1483 sizeof (SymbolDBEngine
), /* instance_size */
1484 0, /* n_preallocs */
1485 (GInstanceInitFunc
) sdb_engine_init
, /* instance_init */
1486 NULL
/* value_table */
1489 our_type
= g_type_register_static (G_TYPE_OBJECT
, "SymbolDBEngine",
1497 symbol_db_engine_new (void)
1499 SymbolDBEngine
*sdbe
;
1501 sdbe
= g_object_new (SYMBOL_TYPE_DB_ENGINE
, NULL
);
1505 /* Will create priv->db_connection, priv->gda_client.
1506 * Connect to database identified by data_source.
1507 * Usually data_source is defined also into priv. We let it here as parameter
1508 * because it is required and cannot be null.
1511 sdb_engine_connect_to_db (SymbolDBEngine
* dbe
, const gchar
* data_source
)
1513 SymbolDBEnginePriv
*priv
;
1515 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
1518 priv
->mutex
= g_mutex_new ();
1519 priv
->signals_queue
= g_async_queue_new ();
1521 if (priv
->db_connection
!= NULL
)
1523 /* if it's the case that the connection isn't NULL, we
1524 * should notify the user
1525 * and return FALSE. It's his task to disconnect and retry to connect */
1526 g_warning ("connection is already established. Please disconnect "
1527 "and then try to reconnect.");
1531 /* create new client */
1532 priv
->gda_client
= gda_client_new ();
1534 /* establish a connection. If the sqlite file does not exist it will
1538 = gda_client_open_connection (priv
->gda_client
, data_source
,
1540 GDA_CONNECTION_OPTIONS_DONT_SHARE
, NULL
);
1542 if (!GDA_IS_CONNECTION (priv
->db_connection
))
1544 g_warning ("could not open connection to %s\n", data_source
);
1548 gda_dict_set_connection (default_dict
, priv
->db_connection
);
1550 DEBUG_PRINT ("connected to database %s", data_source
);
1556 * Creates required tables for the database to work.
1557 * @param tables_sql_file File containing sql code.
1560 sdb_engine_create_db_tables (SymbolDBEngine
* dbe
, gchar
* tables_sql_file
)
1563 GdaCommand
*command
;
1564 SymbolDBEnginePriv
*priv
;
1568 g_return_val_if_fail (tables_sql_file
!= NULL
, FALSE
);
1572 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
1574 /* read the contents of the file */
1575 if (g_file_get_contents (tables_sql_file
, &contents
, &sizez
, &err
) == FALSE
)
1577 g_warning ("Something went wrong while trying to read %s",
1581 g_message ("%s", err
->message
);
1585 command
= gda_command_new (contents
, GDA_COMMAND_TYPE_SQL
,
1586 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
1587 gda_connection_execute_non_select_command (priv
->db_connection
, command
,
1589 gda_command_free (command
);
1596 * Check if the database already exists into the prj_directory
1599 symbol_db_engine_db_exists (SymbolDBEngine
* dbe
, const gchar
* prj_directory
)
1601 SymbolDBEnginePriv
*priv
;
1603 g_return_val_if_fail (prj_directory
!= NULL
, FALSE
);
1607 /* check whether the db filename already exists.*/
1608 gchar
*tmp_file
= g_strdup_printf ("%s/%s.db", prj_directory
,
1611 if (g_file_test (tmp_file
, G_FILE_TEST_EXISTS
) == FALSE
)
1613 DEBUG_PRINT ("db %s does not exist", tmp_file
);
1618 DEBUG_PRINT ("db %s does exist", tmp_file
);
1625 * Open or create a new database at given directory.
1628 symbol_db_engine_open_db (SymbolDBEngine
* dbe
, const gchar
* prj_directory
)
1630 SymbolDBEnginePriv
*priv
;
1631 /* Connection data */
1633 gboolean needs_tables_creation
= FALSE
;
1635 g_return_val_if_fail (prj_directory
!= NULL
, FALSE
);
1639 /* check whether the db filename already exists. If it's not the case
1640 * create the tables for the database. */
1641 gchar
*tmp_file
= g_strdup_printf ("%s/%s.db", prj_directory
,
1644 if (g_file_test (tmp_file
, G_FILE_TEST_EXISTS
) == FALSE
)
1646 needs_tables_creation
= TRUE
;
1651 priv
->data_source
= g_strdup (prj_directory
);
1653 dsn_name
= g_strdup_printf ("DB_DIR=%s;DB_NAME=%s", prj_directory
,
1656 if (gda_config_save_data_source (priv
->data_source
, "SQLite",
1657 dsn_name
, "Anjuta Project",
1658 "", "", FALSE
) == FALSE
)
1663 /* store the dsn name into Priv data. We can avoid to free it here coz it will
1664 * used later again. */
1665 priv
->dsn_name
= dsn_name
;
1667 DEBUG_PRINT ("symbol_db_engine_open_db (): opening/connecting to database...");
1668 sdb_engine_connect_to_db (dbe
, priv
->data_source
);
1670 if (needs_tables_creation
== TRUE
)
1672 DEBUG_PRINT ("symbol_db_engine_open_db (): creating tables: it needs tables...");
1673 sdb_engine_create_db_tables (dbe
, TABLES_SQL
);
1680 * @return -1 on error. Otherwise the id of table
1683 sdb_engine_get_table_id_by_unique_name (SymbolDBEngine
* dbe
, query_type qtype
,
1685 const GValue
* param_value
)
1687 const GdaQuery
*query
;
1688 GdaObject
*query_result
;
1689 GdaParameterList
*par_list
;
1690 GdaParameter
*param
;
1694 /* get prepared query */
1695 if ((query
= sdb_engine_get_query_by_id (dbe
, qtype
)) == NULL
)
1697 g_warning ("query is null");
1701 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1702 == gda_query_get_query_type ((GdaQuery
*) query
))
1704 g_warning ("sdb_engine_get_table_id_by_unique_name: non parsed "
1709 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1711 g_warning ("par_list is NULL!\n");
1715 if ((param
= gda_parameter_list_find_param (par_list
, param_key
)) == NULL
)
1717 g_warning ("sdb_engine_get_table_id_by_unique_name: param is NULL "
1722 gda_parameter_set_value (param
, param_value
);
1724 /* execute the query with parametes just set */
1725 query_result
= gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
,
1728 if (!GDA_IS_DATA_MODEL (query_result
) ||
1729 gda_data_model_get_n_rows (GDA_DATA_MODEL (query_result
)) <= 0)
1731 if (query_result
!= NULL
)
1732 g_object_unref (query_result
);
1736 /* get and parse the results. */
1737 num
= gda_data_model_get_value_at (GDA_DATA_MODEL (query_result
), 0, 0);
1739 table_id
= g_value_get_int (num
);
1740 g_object_unref (query_result
);
1745 * This is the same as sdb_engine_get_table_id_by_unique_name () but for two
1746 * unique parameters. This should be the quickest way. Surely quicker than
1747 * use g_strdup_printf () with a va_list for example.
1748 * @return -1 on error. Otherwise the id of table
1752 sdb_engine_get_table_id_by_unique_name2 (SymbolDBEngine
* dbe
, query_type qtype
,
1754 const GValue
* value1
,
1756 const GValue
* value2
)
1758 const GdaQuery
*query
;
1759 GdaObject
*query_result
;
1760 GdaParameterList
*par_list
;
1761 GdaParameter
*param
;
1765 /* get prepared query */
1766 if ((query
= sdb_engine_get_query_by_id (dbe
, qtype
)) == NULL
)
1768 g_warning ("query is null");
1772 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1773 == gda_query_get_query_type ((GdaQuery
*) query
))
1776 ("sdb_engine_get_table_id_by_unique_name2: non parsed sql error");
1780 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1782 g_warning ("par_list is NULL!\n");
1786 /* look for and set the first parameter */
1787 if ((param
= gda_parameter_list_find_param (par_list
, param_key1
)) == NULL
)
1789 g_warning ("sdb_engine_get_table_id_by_unique_name2: "
1790 "param is NULL from pquery! [par1: %s] [par2: %s]\n",
1791 param_key1
, param_key2
);
1795 gda_parameter_set_value (param
, value1
);
1797 /* ...and the second one */
1798 if ((param
= gda_parameter_list_find_param (par_list
, param_key2
)) == NULL
)
1800 g_warning ("param is NULL from pquery!\n");
1804 gda_parameter_set_value (param
, value2
);
1806 /* execute the query with parametes just set */
1807 query_result
= gda_query_execute ((GdaQuery
*) query
, par_list
,
1810 if (!GDA_IS_DATA_MODEL (query_result
) ||
1811 ((gda_data_model_get_n_rows (GDA_DATA_MODEL (query_result
))) <= 0))
1813 if (query_result
!= NULL
)
1814 g_object_unref (query_result
);
1818 /* get and parse the results. */
1819 num
= gda_data_model_get_value_at (GDA_DATA_MODEL (query_result
), 0, 0);
1821 table_id
= g_value_get_int (num
);
1822 g_object_unref (query_result
);
1827 sdb_engine_get_table_id_by_unique_name3 (SymbolDBEngine
* dbe
, query_type qtype
,
1829 const GValue
* value1
,
1831 const GValue
* value2
,
1833 const GValue
* value3
)
1835 const GdaQuery
*query
;
1836 GdaObject
*query_result
;
1837 GdaParameterList
*par_list
;
1838 GdaParameter
*param
;
1842 /* get prepared query */
1843 if ((query
= sdb_engine_get_query_by_id (dbe
, qtype
)) == NULL
)
1845 g_warning ("query is null");
1849 if (GDA_QUERY_TYPE_NON_PARSED_SQL
1850 == gda_query_get_query_type ((GdaQuery
*) query
))
1853 ("sdb_engine_get_table_id_by_unique_name2: non parsed sql error");
1857 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1859 g_warning ("par_list is NULL!\n");
1863 /* look for and set the first parameter */
1864 if ((param
= gda_parameter_list_find_param (par_list
, param_key1
)) == NULL
)
1866 g_warning ("sdb_engine_get_table_id_by_unique_name2: "
1867 "param is NULL from pquery! [par1: %s] [par2: %s]\n",
1868 param_key1
, param_key2
);
1872 gda_parameter_set_value (param
, value1
);
1874 /* ...and the second one */
1875 if ((param
= gda_parameter_list_find_param (par_list
, param_key2
)) == NULL
)
1877 g_warning ("param is NULL from pquery!\n");
1881 gda_parameter_set_value (param
, value2
);
1883 /* ...and the third one */
1884 if ((param
= gda_parameter_list_find_param (par_list
, param_key3
)) == NULL
)
1886 g_warning ("param is NULL from pquery!\n");
1890 gda_parameter_set_value (param
, value3
);
1893 /* execute the query with parametes just set */
1894 query_result
= gda_query_execute ((GdaQuery
*) query
, par_list
,
1897 if (!GDA_IS_DATA_MODEL (query_result
) ||
1898 gda_data_model_get_n_rows (GDA_DATA_MODEL (query_result
)) <= 0)
1901 if (query_result
!= NULL
)
1902 g_object_unref (query_result
);
1906 /* get and parse the results. */
1907 num
= gda_data_model_get_value_at (GDA_DATA_MODEL (query_result
), 0, 0);
1909 table_id
= g_value_get_int (num
);
1910 g_object_unref (query_result
);
1916 symbol_db_engine_add_new_workspace (SymbolDBEngine
* dbe
,
1917 const gchar
* workspace_name
)
1920 CREATE TABLE workspace (workspace_id integer PRIMARY KEY AUTOINCREMENT,
1921 workspace_name varchar (50) not null unique,
1925 const GdaQuery
*query
;
1926 GdaObject
*query_result
;
1927 GdaParameterList
*par_list
;
1928 GdaParameter
*param
;
1930 SymbolDBEnginePriv
*priv
;
1934 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
1937 sdb_engine_get_query_by_id (dbe
, PREP_QUERY_WORKSPACE_NEW
)) == NULL
)
1939 g_warning ("query is null");
1943 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
1944 gda_query_get_query_type ((GdaQuery
*) query
))
1946 g_warning ("non parsed sql error");
1950 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
1952 g_warning ("par_list is NULL!\n");
1956 if ((param
= gda_parameter_list_find_param (par_list
, "wsname")) == NULL
)
1958 g_warning ("param is NULL from pquery!\n");
1962 value
= gda_value_new (G_TYPE_STRING
);
1963 g_value_set_string (value
, workspace_name
);
1965 gda_parameter_set_value (param
, value
);
1967 /* execute the query with parametes just set */
1970 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, &err
);
1971 gda_value_free (value
);
1974 if (query_result
!= NULL
)
1976 g_object_unref (query_result
);
1981 DEBUG_PRINT ("Error: %s", err
->message
);
1987 * Return the name of the opened project.
1988 * NULL on error. Returned string must be freed by caller.
1991 symbol_db_engine_get_opened_project_name (SymbolDBEngine
* dbe
)
1993 SymbolDBEnginePriv
*priv
;
1994 g_return_val_if_fail (dbe
!= NULL
, NULL
);
1997 g_return_val_if_fail (priv
->db_connection
!= NULL
, NULL
);
1999 return g_strdup (priv
->project_name
);
2003 * Open a new project.
2004 * It will test if project was correctly created.
2007 symbol_db_engine_open_project (SymbolDBEngine
* dbe
, /*gchar* workspace, */
2008 const gchar
* project_name
)
2011 SymbolDBEnginePriv
*priv
;
2016 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
2017 if (symbol_db_engine_is_project_opened (dbe
, project_name
) == TRUE
) {
2018 g_warning ("symbol_db_engine_open_project (): "
2019 "project already opened, %s (priv %s)", project_name
,
2020 priv
->project_name
);
2024 value
= gda_value_new (G_TYPE_STRING
);
2025 g_value_set_string (value
, project_name
);
2027 /* test the existence of the project in db */
2028 if ((prj_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2029 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME
,
2033 DEBUG_PRINT ("symbol_db_engine_open_project (): no project name found");
2034 gda_value_free (value
);
2038 gda_value_free (value
);
2040 /* open the project... */
2041 priv
->project_name
= g_strdup (project_name
);
2048 symbol_db_engine_close_project (SymbolDBEngine
*dbe
, const gchar
* project_name
)
2050 SymbolDBEnginePriv
*priv
;
2054 g_free (priv
->project_name
);
2055 priv
->project_name
= NULL
;
2057 return sdb_engine_disconnect_from_db (dbe
);
2062 * @param workspace Can be NULL. In that case a default workspace will be created,
2063 * and project will depend on that.
2064 * @param project Project name. Must NOT be NULL.
2067 symbol_db_engine_add_new_project (SymbolDBEngine
* dbe
, const gchar
* workspace
,
2068 const gchar
* project
)
2071 CREATE TABLE project (project_id integer PRIMARY KEY AUTOINCREMENT,
2072 project_name varchar (50) not null unique,
2073 wrkspace_id integer REFERENCES workspace (workspace_id),
2077 const GdaQuery
*query
;
2078 GdaObject
*query_result
;
2079 GdaParameterList
*par_list
;
2080 GdaParameter
*param
;
2082 const gchar
*workspace_name
;
2084 SymbolDBEnginePriv
*priv
;
2086 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
2090 if (symbol_db_engine_is_project_opened (dbe
, project
) == TRUE
)
2092 g_warning ("You have an already opened project. Cannot continue.");
2096 if (workspace
== NULL
)
2098 workspace_name
= "anjuta_workspace_default";
2100 DEBUG_PRINT ("adding default workspace... %s", workspace_name
);
2101 value
= gda_value_new (G_TYPE_STRING
);
2102 g_value_set_string (value
, workspace_name
);
2104 if ((wks_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2105 PREP_QUERY_GET_WORKSPACE_ID_BY_UNIQUE_NAME
,
2109 if (symbol_db_engine_add_new_workspace (dbe
, workspace_name
) == FALSE
)
2111 gda_value_free (value
);
2112 DEBUG_PRINT ("Project cannot be added because a default workspace "
2113 "cannot be created");
2117 gda_value_free (value
);
2121 workspace_name
= workspace
;
2124 value
= gda_value_new (G_TYPE_STRING
);
2125 g_value_set_string (value
, workspace_name
);
2127 /* get workspace id */
2128 if ((wks_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2129 PREP_QUERY_GET_WORKSPACE_ID_BY_UNIQUE_NAME
,
2133 DEBUG_PRINT ("symbol_db_engine_add_new_project (): no workspace id");
2134 gda_value_free (value
);
2138 /* insert new project */
2140 sdb_engine_get_query_by_id (dbe
, PREP_QUERY_PROJECT_NEW
)) == NULL
)
2142 g_warning ("query is null");
2143 gda_value_free (value
);
2147 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2148 gda_query_get_query_type ((GdaQuery
*) query
))
2150 g_warning ("non parsed sql error");
2151 gda_value_free (value
);
2155 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2157 g_warning ("par_list is NULL!\n");
2158 gda_value_free (value
);
2162 if ((param
= gda_parameter_list_find_param (par_list
, "prjname")) == NULL
)
2164 g_warning ("param prjname is NULL from pquery!");
2165 gda_value_free (value
);
2169 gda_value_reset_with_type (value
, G_TYPE_STRING
);
2170 g_value_set_string (value
, project
);
2171 gda_parameter_set_value (param
, value
);
2173 if ((param
= gda_parameter_list_find_param (par_list
, "wsid")) == NULL
)
2175 g_warning ("param is NULL from pquery!");
2179 gda_value_reset_with_type (value
, G_TYPE_INT
);
2180 g_value_set_int (value
, wks_id
);
2182 gda_parameter_set_value (param
, value
);
2184 /* execute the query with parametes just set */
2186 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2187 gda_value_free (value
);
2189 if (query_result
!= NULL
)
2191 g_object_unref (query_result
);
2200 sdb_engine_add_new_language (SymbolDBEngine
* dbe
, const gchar
*language
)
2203 CREATE TABLE language (language_id integer PRIMARY KEY AUTOINCREMENT,
2204 language_name varchar (50) not null unique);
2209 g_return_val_if_fail (language
!= NULL
, -1);
2211 value
= gda_value_new (G_TYPE_STRING
);
2212 g_value_set_string (value
, language
);
2214 /* check for an already existing table with language "name". */
2215 if ((table_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2216 PREP_QUERY_GET_LANGUAGE_ID_BY_UNIQUE_NAME
,
2221 /* insert a new entry on db */
2222 const GdaQuery
*query
;
2223 GdaObject
*query_result
;
2224 GdaParameterList
*par_list
;
2225 GdaParameter
*param
;
2228 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_LANGUAGE_NEW
))
2231 g_warning ("query is null");
2235 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2236 gda_query_get_query_type ((GdaQuery
*) query
))
2238 g_warning ("non parsed sql error");
2243 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2245 g_warning ("par_list is NULL!\n");
2250 gda_parameter_list_find_param (par_list
, "langname")) == NULL
)
2252 g_warning ("param langname is NULL from pquery!");
2256 value
= gda_value_new (G_TYPE_STRING
);
2257 g_value_set_string (value
, language
);
2259 gda_parameter_set_value (param
, value
);
2260 gda_value_free (value
);
2261 /* execute the query with parametes just set */
2263 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2265 if (query_result
!= NULL
)
2267 table_id
= sdb_engine_get_last_insert_id (dbe
);
2268 g_object_unref (query_result
);
2275 gda_value_free (value
);
2280 /* Add a file to project.
2281 * This function requires an opened db, i.e. calling before
2282 * symbol_db_engine_open_db ()
2283 * filepath: referes to a full file path.
2284 * WARNING: we suppose that project is already opened.
2287 sdb_engine_add_new_file (SymbolDBEngine
* dbe
, const gchar
* project
,
2288 const gchar
* filepath
, const gchar
* language
)
2291 CREATE TABLE file (file_id integer PRIMARY KEY AUTOINCREMENT,
2292 file_path TEXT not null unique,
2293 prj_id integer REFERENCES project (projec_id),
2294 lang_id integer REFERENCES language (language_id),
2298 SymbolDBEnginePriv
*priv
;
2306 value
= gda_value_new (G_TYPE_STRING
);
2307 g_value_set_string (value
, project
);
2309 /* check for an already existing table with project "project". */
2310 if ((project_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2311 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME
,
2315 g_warning ("no project with that name exists");
2316 gda_value_free (value
);
2320 gda_value_free (value
);
2321 value
= gda_value_new (G_TYPE_STRING
);
2322 /* we're gonna set the file relative to the project folder, not the full one.
2323 * e.g.: we have a file on disk: "/tmp/foo/src/file.c" and a datasource located on
2324 * "/tmp/foo/". The entry on db will be "/src/file.c"
2326 g_value_set_string (value
, filepath
+ strlen(priv
->data_source
));
2328 if ((file_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2329 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME
,
2333 /* insert a new entry on db */
2334 const GdaQuery
*query
;
2335 GdaObject
*query_result
;
2336 GdaParameterList
*par_list
;
2337 GdaParameter
*param
;
2340 language_id
= sdb_engine_add_new_language (dbe
, language
);
2342 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_FILE_NEW
))
2345 g_warning ("query is null");
2349 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2350 gda_query_get_query_type ((GdaQuery
*) query
))
2352 g_warning ("non parsed sql error");
2357 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2359 g_warning ("par_list is NULL!\n");
2363 /* filepath parameter */
2365 gda_parameter_list_find_param (par_list
, "filepath")) == NULL
)
2367 g_warning ("param filepath is NULL from pquery!");
2371 value
= gda_value_new (G_TYPE_STRING
);
2372 /* relative filepath */
2373 g_value_set_string (value
, filepath
+ strlen(priv
->data_source
));
2374 gda_parameter_set_value (param
, value
);
2376 /* project id parameter */
2377 if ((param
= gda_parameter_list_find_param (par_list
, "prjid")) == NULL
)
2379 g_warning ("param prjid is NULL from pquery!");
2383 gda_value_reset_with_type (value
, G_TYPE_INT
);
2384 g_value_set_int (value
, project_id
);
2385 gda_parameter_set_value (param
, value
);
2387 /* language id parameter */
2389 gda_parameter_list_find_param (par_list
, "langid")) == NULL
)
2391 g_warning ("param langid is NULL from pquery!");
2395 gda_value_reset_with_type (value
, G_TYPE_INT
);
2396 g_value_set_int (value
, language_id
);
2397 gda_parameter_set_value (param
, value
);
2398 gda_value_free (value
);
2400 /* execute the query with parametes just set */
2401 query_result
= gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2403 if (query_result
!= NULL
)
2404 g_object_unref (query_result
);
2406 gda_value_free (value
);
2413 sdb_engine_prepare_executing_commands (SymbolDBEngine
*dbe
)
2415 GdaCommand
*command
;
2416 SymbolDBEnginePriv
*priv
;
2419 command
= gda_command_new ("PRAGMA page_size = 32768", GDA_COMMAND_TYPE_SQL
,
2420 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
2421 gda_connection_execute_non_select_command (priv
->db_connection
,
2422 command
, NULL
, NULL
);
2423 gda_command_free (command
);
2425 command
= gda_command_new ("PRAGMA cache_size = 12288", GDA_COMMAND_TYPE_SQL
,
2426 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
2427 gda_connection_execute_non_select_command (priv
->db_connection
,
2428 command
, NULL
, NULL
);
2429 gda_command_free (command
);
2431 command
= gda_command_new ("PRAGMA synchronous = OFF", GDA_COMMAND_TYPE_SQL
,
2432 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
2433 gda_connection_execute_non_select_command (priv
->db_connection
,
2434 command
, NULL
, NULL
);
2435 gda_command_free (command
);
2437 command
= gda_command_new ("PRAGMA temp_store = MEMORY", GDA_COMMAND_TYPE_SQL
,
2438 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
2439 gda_connection_execute_non_select_command (priv
->db_connection
,
2440 command
, NULL
, NULL
);
2441 gda_command_free (command
);
2445 symbol_db_engine_add_new_files (SymbolDBEngine
* dbe
, const gchar
* project
,
2446 const GPtrArray
* files_path
,
2447 const GPtrArray
* languages
,
2448 gboolean scan_symbols
)
2451 SymbolDBEnginePriv
*priv
;
2453 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
2456 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
2457 g_return_val_if_fail (project
!= NULL
, FALSE
);
2459 /* FIXME try this... to see if things speed up*/
2460 sdb_engine_prepare_executing_commands (dbe
);
2463 if (symbol_db_engine_is_project_opened (dbe
, project
) == FALSE
)
2465 g_warning ("your project isn't opened, %s (priv %s)", project
,
2466 priv
->project_name
);
2470 for (i
= 0; i
< files_path
->len
; i
++)
2472 gchar
*node
= (gchar
*) g_ptr_array_index (files_path
, i
);
2473 gchar
*node_lang
= (gchar
*) g_ptr_array_index (languages
, i
);
2475 /* test the existance of node file */
2476 if (g_file_test (node
, G_FILE_TEST_EXISTS
) == FALSE
)
2478 g_warning ("File %s doesn't exist", node
);
2482 if (sdb_engine_add_new_file (dbe
, project
, node
, node_lang
) == FALSE
)
2484 g_warning ("Error processing file %s", node
);
2489 /* perform the scan of files. It will spawn a fork() process with
2490 * AnjutaLauncher and ctags in server mode. After the ctags cmd has been
2491 * executed, the populating process'll take place.
2495 return sdb_engine_scan_files_1 (dbe
, files_path
, NULL
, FALSE
);
2502 sdb_engine_add_new_sym_type (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
)
2505 CREATE TABLE sym_type (type_id integer PRIMARY KEY AUTOINCREMENT,
2506 type varchar (256) not null ,
2507 type_name varchar (256) not null ,
2508 unique (type, type_name)
2512 const gchar
*type_name
;
2515 const GdaQuery
*query
;
2516 GdaObject
* query_result
;
2517 GdaParameterList
*par_list
;
2518 GdaParameter
*param
;
2521 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2523 type
= tag_entry
->kind
;
2524 type_name
= tag_entry
->name
;
2526 /* it does not exist. Create a new tuple. */
2527 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SYM_TYPE_NEW
))
2530 g_warning ("query is null");
2534 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2535 gda_query_get_query_type ((GdaQuery
*) query
))
2537 g_warning ("non parsed sql error");
2542 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2544 g_warning ("par_list is NULL!\n");
2548 /* type parameter */
2549 if ((param
= gda_parameter_list_find_param (par_list
, "type")) == NULL
)
2551 g_warning ("param type is NULL from pquery!");
2555 value
= gda_value_new (G_TYPE_STRING
);
2556 g_value_set_string (value
, type
);
2557 gda_parameter_set_value (param
, value
);
2559 /* type_name parameter */
2561 gda_parameter_list_find_param (par_list
, "typename")) == NULL
)
2563 g_warning ("param typename is NULL from pquery!");
2567 gda_value_reset_with_type (value
, G_TYPE_STRING
);
2568 g_value_set_string (value
, type_name
);
2569 gda_parameter_set_value (param
, value
);
2570 gda_value_free (value
);
2572 /* execute the query with parametes just set */
2574 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2576 if (query_result
!= NULL
)
2578 g_object_unref (query_result
);
2579 table_id
= sdb_engine_get_last_insert_id (dbe
);
2583 GValue
*value1
, *value2
;
2585 value1
= gda_value_new (G_TYPE_STRING
);
2586 g_value_set_string (value1
, type
);
2588 value2
= gda_value_new (G_TYPE_STRING
);
2589 g_value_set_string (value2
, type_name
);
2591 if ((table_id
= sdb_engine_get_table_id_by_unique_name2 (dbe
,
2592 PREP_QUERY_GET_SYM_TYPE_ID
,
2600 gda_value_free (value1
);
2601 gda_value_free (value2
);
2608 sdb_engine_add_new_sym_kind (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
)
2611 CREATE TABLE sym_kind (sym_kind_id integer PRIMARY KEY AUTOINCREMENT,
2612 kind_name varchar (50) not null unique
2615 const gchar
*kind_name
;
2619 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2621 kind_name
= tag_entry
->kind
;
2623 /* no kind associated with current tag */
2624 if (kind_name
== NULL
)
2627 value
= gda_value_new (G_TYPE_STRING
);
2628 g_value_set_string (value
, kind_name
);
2630 if ((table_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2631 PREP_QUERY_GET_SYM_KIND_BY_UNIQUE_NAME
,
2635 const GdaQuery
*query
;
2636 GdaObject
*query_result
;
2637 GdaParameterList
*par_list
;
2638 GdaParameter
*param
;
2641 /* not found. Go on with inserting */
2642 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SYM_KIND_NEW
))
2645 g_warning ("query is null");
2649 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2650 gda_query_get_query_type ((GdaQuery
*) query
))
2652 g_warning ("non parsed sql error");
2657 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2659 g_warning ("par_list is NULL!\n");
2663 /* kindname parameter */
2665 gda_parameter_list_find_param (par_list
, "kindname")) == NULL
)
2667 g_warning ("param kindname is NULL from pquery!");
2671 value
= gda_value_new (G_TYPE_STRING
);
2672 g_value_set_string (value
, kind_name
);
2673 gda_parameter_set_value (param
, value
);
2674 gda_value_free (value
);
2676 /* execute the query with parametes just set */
2678 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2680 if (query_result
!= NULL
)
2682 table_id
= sdb_engine_get_last_insert_id (dbe
);
2683 g_object_unref (query_result
);
2690 gda_value_free (value
);
2695 sdb_engine_add_new_sym_access (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
)
2698 CREATE TABLE sym_access (access_kind_id integer PRIMARY KEY AUTOINCREMENT,
2699 access_name varchar (50) not null unique
2702 const gchar
*access
;
2706 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2708 if ((access
= tagsField (tag_entry
, "access")) == NULL
)
2710 /* no access associated with current tag */
2714 value
= gda_value_new (G_TYPE_STRING
);
2715 g_value_set_string (value
, access
);
2717 if ((table_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2718 PREP_QUERY_GET_SYM_ACCESS_BY_UNIQUE_NAME
,
2722 const GdaQuery
*query
;
2723 GdaObject
*query_result
;
2724 GdaParameterList
*par_list
;
2725 GdaParameter
*param
;
2728 /* not found. Go on with inserting */
2730 sdb_engine_get_query_by_id (dbe
,
2731 PREP_QUERY_SYM_ACCESS_NEW
)) == NULL
)
2733 g_warning ("query is null");
2737 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2738 gda_query_get_query_type ((GdaQuery
*) query
))
2740 g_warning ("non parsed sql error");
2745 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2747 g_warning ("par_list is NULL!\n");
2751 /* accesskind parameter */
2753 gda_parameter_list_find_param (par_list
, "accesskind")) == NULL
)
2755 g_warning ("param accesskind is NULL from pquery!");
2759 value
= gda_value_new (G_TYPE_STRING
);
2760 g_value_set_string (value
, access
);
2761 gda_parameter_set_value (param
, value
);
2762 gda_value_free (value
);
2764 /* execute the query with parametes just set */
2766 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2768 if (query_result
!= NULL
)
2770 table_id
= sdb_engine_get_last_insert_id (dbe
);
2771 g_object_unref (query_result
);
2778 gda_value_free (value
);
2783 sdb_engine_add_new_sym_implementation (SymbolDBEngine
* dbe
,
2784 tagEntry
* tag_entry
)
2787 CREATE TABLE sym_implementation (sym_impl_id integer PRIMARY KEY AUTOINCREMENT,
2788 implementation_name varchar (50) not null unique
2791 const gchar
*implementation
;
2795 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2797 if ((implementation
= tagsField (tag_entry
, "implementation")) == NULL
)
2799 /* no implementation associated with current tag */
2803 value
= gda_value_new (G_TYPE_STRING
);
2804 g_value_set_string (value
, implementation
);
2806 if ((table_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
2807 PREP_QUERY_GET_SYM_IMPLEMENTATION_BY_UNIQUE_NAME
,
2811 const GdaQuery
*query
;
2812 GdaObject
*query_result
;
2813 GdaParameterList
*par_list
;
2814 GdaParameter
*param
;
2817 /* not found. Go on with inserting */
2819 sdb_engine_get_query_by_id (dbe
,
2820 PREP_QUERY_SYM_IMPLEMENTATION_NEW
)) ==
2823 g_warning ("query is null");
2827 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2828 gda_query_get_query_type ((GdaQuery
*) query
))
2830 g_warning ("non parsed sql error");
2835 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2837 g_warning ("par_list is NULL!\n");
2841 /* implekind parameter */
2843 gda_parameter_list_find_param (par_list
, "implekind")) == NULL
)
2845 g_warning ("param implekind is NULL from pquery!");
2849 value
= gda_value_new (G_TYPE_STRING
);
2850 g_value_set_string (value
, implementation
);
2851 gda_parameter_set_value (param
, value
);
2852 gda_value_free (value
);
2854 /* execute the query with parametes just set */
2856 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2858 if (query_result
!= NULL
)
2860 table_id
= sdb_engine_get_last_insert_id (dbe
);
2861 g_object_unref (query_result
);
2868 gda_value_free (value
);
2874 sdb_engine_add_new_heritage (SymbolDBEngine
* dbe
, gint base_symbol_id
,
2875 gint derived_symbol_id
)
2878 CREATE TABLE heritage (symbol_id_base integer REFERENCES symbol (symbol_id),
2879 symbol_id_derived integer REFERENCES symbol (symbol_id),
2880 PRIMARY KEY (symbol_id_base, symbol_id_derived)
2883 const GdaQuery
*query
;
2884 GdaObject
*query_result
;
2885 GdaParameterList
*par_list
;
2886 GdaParameter
*param
;
2889 g_return_if_fail (base_symbol_id
> 0);
2890 g_return_if_fail (derived_symbol_id
> 0);
2892 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_HERITAGE_NEW
))
2895 g_warning ("query is null");
2899 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2900 gda_query_get_query_type ((GdaQuery
*) query
))
2902 g_warning ("non parsed sql error");
2906 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2908 g_warning ("par_list is NULL!\n");
2912 /* symbase parameter */
2913 if ((param
= gda_parameter_list_find_param (par_list
, "symbase")) == NULL
)
2915 g_warning ("param symbase is NULL from pquery!");
2919 value
= gda_value_new (G_TYPE_INT
);
2920 g_value_set_int (value
, base_symbol_id
);
2921 gda_parameter_set_value (param
, value
);
2923 /* symderived id parameter */
2925 gda_parameter_list_find_param (par_list
, "symderived")) == NULL
)
2927 g_warning ("param symderived is NULL from pquery!");
2931 gda_value_reset_with_type (value
, G_TYPE_INT
);
2932 g_value_set_int (value
, derived_symbol_id
);
2933 gda_parameter_set_value (param
, value
);
2934 gda_value_free (value
);
2936 /* execute the query with parametes just set */
2938 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
2940 if (query_result
!= NULL
)
2941 g_object_unref (query_result
);
2946 sdb_engine_add_new_scope_definition (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
,
2950 CREATE TABLE scope (scope_id integer PRIMARY KEY AUTOINCREMENT,
2951 scope_name varchar(256) not null,
2952 type_id integer REFERENCES sym_type (type_id),
2953 unique (scope_name, type_id)
2958 const GdaQuery
*query
;
2959 GdaObject
*query_result
;
2960 GdaParameterList
*par_list
;
2961 GdaParameter
*param
;
2964 g_return_val_if_fail (tag_entry
!= NULL
, -1);
2965 g_return_val_if_fail (tag_entry
->kind
!= NULL
, -1);
2967 /* This symbol will define a scope which name is tag_entry->name
2968 * For example if we get a tag MyFoo with kind "namespace", it will define
2969 * the "MyFoo" scope, which type is "namespace MyFoo"
2971 scope
= tag_entry
->name
;
2973 /* filter out 'variable' and 'member' kinds. They define no scope. */
2974 if (strcmp (tag_entry
->kind
, "variable") == 0 ||
2975 strcmp (tag_entry
->kind
, "member") == 0)
2980 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SCOPE_NEW
))
2983 g_warning ("query is null");
2987 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
2988 gda_query_get_query_type ((GdaQuery
*) query
))
2990 g_warning ("non parsed sql error");
2995 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
2997 g_warning ("par_list is NULL!\n");
3001 /* scope parameter */
3002 if ((param
= gda_parameter_list_find_param (par_list
, "scope")) == NULL
)
3004 g_warning ("param scope is NULL from pquery!");
3008 value
= gda_value_new (G_TYPE_STRING
);
3009 g_value_set_string (value
, scope
);
3010 gda_parameter_set_value (param
, value
);
3012 /* typeid parameter */
3014 gda_parameter_list_find_param (par_list
, "typeid")) == NULL
)
3016 g_warning ("param typeid is NULL from pquery!");
3020 gda_value_reset_with_type (value
, G_TYPE_INT
);
3021 g_value_set_int (value
, type_table_id
);
3022 gda_parameter_set_value (param
, value
);
3023 gda_value_free (value
);
3025 /* execute the query with parameters just set */
3026 query_result
= gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
3027 if (query_result
== NULL
)
3029 GValue
*value1
, *value2
;
3030 /* DEBUG_PRINT ("sdb_engine_add_new_scope_definition (): BAD INSERTION "
3031 "[%s %s]", tag_entry->kind, scope);
3033 /* let's check for an already present scope table with scope and type_id infos. */
3034 value1
= gda_value_new (G_TYPE_STRING
);
3035 g_value_set_string (value1
, scope
);
3037 value2
= gda_value_new (G_TYPE_INT
);
3038 g_value_set_int (value2
, type_table_id
);
3040 if ((table_id
= sdb_engine_get_table_id_by_unique_name2 (dbe
,
3041 PREP_QUERY_GET_SCOPE_ID
,
3051 gda_value_free (value1
);
3052 gda_value_free (value2
);
3055 table_id
= sdb_engine_get_last_insert_id (dbe
);
3056 g_object_unref (query_result
);
3063 * Saves the tagEntry info for a second pass parsing.
3064 * Usually we don't know all the symbol at the first scan of the tags. We need
3065 * a second one. These tuples are created for that purpose.
3067 * @return the table_id of the inserted tuple. -1 on error.
3070 sdb_engine_add_new_tmp_heritage_scope (SymbolDBEngine
* dbe
,
3071 tagEntry
* tag_entry
,
3072 gint symbol_referer_id
)
3075 CREATE TABLE __tmp_heritage_scope (tmp_heritage_scope_id integer PRIMARY KEY
3077 symbol_referer_id integer not null,
3078 field_inherits varchar(256) not null,
3079 field_struct varchar(256),
3080 field_typeref varchar(256),
3081 field_enum varchar(256),
3082 field_union varchar(256),
3083 field_class varchar(256),
3084 field_namespace varchar(256)
3087 const GdaQuery
*query
;
3088 GdaObject
*query_result
;
3089 GdaParameterList
*par_list
;
3090 GdaParameter
*param
;
3093 const gchar
*field_inherits
, *field_struct
, *field_typeref
,
3094 *field_enum
, *field_union
, *field_class
, *field_namespace
;
3097 g_return_val_if_fail (tag_entry
!= NULL
, -1);
3102 if ((field_inherits
= tagsField (tag_entry
, "inherits")) == NULL
)
3104 field_inherits
= "";
3109 if ((field_struct
= tagsField (tag_entry
, "struct")) == NULL
)
3116 if ((field_typeref
= tagsField (tag_entry
, "typeref")) == NULL
)
3123 if ((field_enum
= tagsField (tag_entry
, "enum")) == NULL
)
3130 if ((field_union
= tagsField (tag_entry
, "union")) == NULL
)
3137 if ((field_class
= tagsField (tag_entry
, "class")) == NULL
)
3144 if ((field_namespace
= tagsField (tag_entry
, "namespace")) == NULL
)
3146 field_namespace
= "";
3155 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_TMP_HERITAGE_NEW
))
3158 g_warning ("query is null");
3162 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3163 gda_query_get_query_type ((GdaQuery
*) query
))
3165 g_warning ("non parsed sql error");
3169 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
3171 g_warning ("par_list is NULL!\n");
3175 /* symreferid parameter */
3177 gda_parameter_list_find_param (par_list
, "symreferid")) == NULL
)
3179 g_warning ("param symreferid is NULL from pquery!");
3183 value
= gda_value_new (G_TYPE_INT
);
3184 g_value_set_int (value
, symbol_referer_id
);
3185 gda_parameter_set_value (param
, value
);
3187 /* finherits parameter */
3188 if ((param
= gda_parameter_list_find_param (par_list
, "finherits")) == NULL
)
3190 g_warning ("param finherits is NULL from pquery!");
3194 gda_value_reset_with_type (value
, G_TYPE_STRING
);
3195 g_value_set_string (value
, field_inherits
);
3196 gda_parameter_set_value (param
, value
);
3198 /* fstruct parameter */
3199 if ((param
= gda_parameter_list_find_param (par_list
, "fstruct")) == NULL
)
3201 g_warning ("param fstruct is NULL from pquery!");
3205 gda_value_reset_with_type (value
, G_TYPE_STRING
);
3206 g_value_set_string (value
, field_struct
);
3207 gda_parameter_set_value (param
, value
);
3209 /* ftyperef parameter */
3210 if ((param
= gda_parameter_list_find_param (par_list
, "ftyperef")) == NULL
)
3212 g_warning ("param ftyperef is NULL from pquery!");
3216 gda_value_reset_with_type (value
, G_TYPE_STRING
);
3217 g_value_set_string (value
, field_typeref
);
3218 gda_parameter_set_value (param
, value
);
3220 /* fenum parameter */
3221 if ((param
= gda_parameter_list_find_param (par_list
, "fenum")) == NULL
)
3223 g_warning ("param fenum is NULL from pquery!");
3227 gda_value_reset_with_type (value
, G_TYPE_STRING
);
3228 g_value_set_string (value
, field_enum
);
3229 gda_parameter_set_value (param
, value
);
3231 /* funion parameter */
3232 if ((param
= gda_parameter_list_find_param (par_list
, "funion")) == NULL
)
3234 g_warning ("param funion is NULL from pquery!");
3238 gda_value_reset_with_type (value
, G_TYPE_STRING
);
3239 g_value_set_string (value
, field_union
);
3240 gda_parameter_set_value (param
, value
);
3242 /* fclass parameter */
3243 if ((param
= gda_parameter_list_find_param (par_list
, "fclass")) == NULL
)
3245 g_warning ("param fclass is NULL from pquery!");
3249 gda_value_reset_with_type (value
, G_TYPE_STRING
);
3250 g_value_set_string (value
, field_class
);
3251 gda_parameter_set_value (param
, value
);
3253 /* fnamespace parameter */
3255 gda_parameter_list_find_param (par_list
, "fnamespace")) == NULL
)
3257 g_warning ("param fnamespace is NULL from pquery!");
3261 gda_value_reset_with_type (value
, G_TYPE_STRING
);
3262 g_value_set_string (value
, field_namespace
);
3263 gda_parameter_set_value (param
, value
);
3264 gda_value_free (value
);
3267 /* execute the query with parametes just set */
3269 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
3271 if (query_result
!= NULL
)
3273 table_id
= sdb_engine_get_last_insert_id (dbe
);
3274 g_object_unref (query_result
);
3284 /** Return the symbol_id of the changed symbol */
3286 sdb_engine_second_pass_update_scope_1 (SymbolDBEngine
* dbe
,
3287 GdaDataModel
* data
, gint data_row
,
3289 const GValue
* token_value
)
3292 GValue
*value1
, *value2
, *value
;
3293 const GValue
*value_id2
;
3294 gint symbol_referer_id
;
3295 const gchar
*tmp_str
;
3296 gchar
**tmp_str_splitted
;
3297 gint tmp_str_splitted_length
;
3298 gchar
*object_name
= NULL
;
3299 gboolean free_token_name
= FALSE
;
3300 const GdaQuery
*query
;
3301 GdaParameterList
*par_list
;
3302 GdaParameter
*param
;
3303 SymbolDBEnginePriv
*priv
;
3305 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
3306 g_return_val_if_fail (G_VALUE_HOLDS_STRING (token_value
), FALSE
);
3309 tmp_str
= g_value_get_string (token_value
);
3311 /* we don't need empty strings */
3312 if (strcmp (tmp_str
, "") == 0)
3317 /* DEBUG_PRINT ("sdb_engine_second_pass_update_scope_1 ()---------------------");
3318 DEBUG_PRINT ("sdb_engine_second_pass_update_scope_1 (): %s", tmp_str);*/
3320 /* we could have something like "First::Second::Third::Fourth" as tmp_str, so
3321 * take only the lastscope, in this case 'Fourth'.
3323 tmp_str_splitted
= g_strsplit (tmp_str
, ":", 0);
3324 tmp_str_splitted_length
= g_strv_length (tmp_str_splitted
);
3326 if (tmp_str_splitted_length
> 0)
3328 /* handle special typedef case. Usually we have something like struct:my_foo.
3329 * splitting we have [0]-> struct [1]-> my_foo
3331 if (strcmp (token_name
, "typedef") == 0)
3333 free_token_name
= TRUE
;
3334 token_name
= g_strdup (tmp_str_splitted
[0]);
3337 object_name
= g_strdup (tmp_str_splitted
[tmp_str_splitted_length
- 1]);
3341 g_strfreev (tmp_str_splitted
);
3345 g_strfreev (tmp_str_splitted
);
3347 /* DEBUG_PRINT ("sdb_engine_second_pass_update_scope_1(): got %s %s (from %s)",
3348 token_name, object_name, tmp_str); */
3350 value1
= gda_value_new (G_TYPE_STRING
);
3351 g_value_set_string (value1
, token_name
);
3353 value2
= gda_value_new (G_TYPE_STRING
);
3354 g_value_set_string (value2
, object_name
);
3356 if ((scope_id
= sdb_engine_get_table_id_by_unique_name2 (dbe
,
3357 PREP_QUERY_GET_SYMBOL_SCOPE_DEFINITION_ID
,
3363 if (free_token_name
)
3364 g_free (token_name
);
3366 gda_value_free (value1
);
3367 gda_value_free (value2
);
3370 gda_value_free (value1
);
3371 gda_value_free (value2
);
3373 if (free_token_name
)
3374 g_free (token_name
);
3377 /* if we reach this point we should have a good scope_id.
3378 * Go on with symbol updating.
3380 value_id2
= gda_data_model_get_value_at_col_name (data
, "symbol_referer_id",
3382 symbol_referer_id
= g_value_get_int (value_id2
);
3384 /* DEBUG_PRINT ("sdb_engine_second_pass_update_scope_1 () :updating sym %d "
3386 symbol_referer_id, scope_id);*/
3388 if ((query
= sdb_engine_get_query_by_id (dbe
,
3389 PREP_QUERY_UPDATE_SYMBOL_SCOPE_ID
))
3392 g_warning ("query is null");
3396 if (GDA_QUERY_TYPE_NON_PARSED_SQL
3397 == gda_query_get_query_type ((GdaQuery
*) query
))
3399 g_warning ("non parsed sql error");
3403 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
3405 g_warning ("par_list is NULL!\n");
3409 /* scopeid parameter */
3410 if ((param
= gda_parameter_list_find_param (par_list
, "scopeid")) == NULL
)
3412 g_warning ("param scopeid is NULL from pquery!");
3416 value
= gda_value_new (G_TYPE_INT
);
3417 g_value_set_int (value
, scope_id
);
3418 gda_parameter_set_value (param
, value
);
3420 /* symbolid parameter */
3421 if ((param
= gda_parameter_list_find_param (par_list
, "symbolid")) == NULL
)
3423 g_warning ("param symbolid is NULL from pquery!");
3427 gda_value_reset_with_type (value
, G_TYPE_INT
);
3428 g_value_set_int (value
, symbol_referer_id
);
3429 gda_parameter_set_value (param
, value
);
3430 gda_value_free (value
);
3432 /* execute the query with parametes just set */
3433 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
3435 return symbol_referer_id
;
3440 * @param data Must be filled with some values. It must have num_rows > 0
3441 * @note *CALL THIS BEFORE second_pass_update_heritage ()*
3442 * @note *DO NOT FREE data* inside this function.
3445 sdb_engine_second_pass_update_scope (SymbolDBEngine
* dbe
, GdaDataModel
* data
)
3448 * Fill up the scope.
3449 * The case: "my_foo_func_1" is the name of the current tag parsed.
3450 * Suppose we have a namespace MyFooNamespace, under which is declared
3451 * a class MyFooClass. Under that class there are some funcs like
3452 * my_foo_func_1 () etc. ctags will present us this info about
3454 * "class : MyFooNamespace::MyFooClass"
3455 * but hey! We don't need to know the namespace here, we just want to
3456 * know that my_foo_func_1 is in the scope of MyFooClass. That one will
3457 * then be mapped inside MyFooNamespace, but that's another thing.
3458 * Go on with the parsing then.
3462 for (i
= 0; i
< gda_data_model_get_n_rows (data
); i
++)
3467 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3471 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "class",
3476 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3480 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "struct",
3485 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3489 /* this is a "typedef", not a "typeref". */
3490 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "typedef",
3495 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3499 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "enum", value
);
3503 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3507 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "union",
3512 (GValue
*) gda_data_model_get_value_at_col_name (data
,
3516 sdb_engine_second_pass_update_scope_1 (dbe
, data
, i
, "namespace",
3524 * @param data Must be filled with some values. It must have num_rows > 0
3525 * @note *CALL THIS AFTER second_pass_update_scope ()*
3528 sdb_engine_second_pass_update_heritage (SymbolDBEngine
* dbe
,
3529 GdaDataModel
* data
)
3532 SymbolDBEnginePriv
*priv
;
3534 g_return_if_fail (dbe
!= NULL
);
3538 for (i
= 0; i
< gda_data_model_get_n_rows (data
); i
++)
3540 const GValue
*value
;
3541 const gchar
*inherits
;
3543 gchar
**inherits_list
;
3546 value
= gda_data_model_get_value_at_col_name (data
,
3547 "field_inherits", i
);
3548 inherits
= g_value_get_string (value
);
3550 /* there can be multiple inheritance. Check that. */
3551 inherits_list
= g_strsplit (inherits
, ",", 0);
3553 if (inherits_list
!= NULL
)
3554 DEBUG_PRINT ("inherits %s\n", inherits
);
3556 /* retrieve as much info as we can from the items */
3557 for (j
= 0; j
< g_strv_length (inherits_list
); j
++)
3561 gchar
*namespace_name
;
3562 gint namespaces_length
;
3564 gint derived_klass_id
;
3565 const GValue
*value
;
3567 item
= inherits_list
[j
];
3568 DEBUG_PRINT ("heritage %s\n", item
);
3570 /* A item may have this string form:
3571 * MyFooNamespace1::MyFooNamespace2::MyFooClass
3572 * We should find the field 'MyFooNamespace2' because it's the one
3573 * that is reachable by the scope_id value of the symbol.
3576 namespaces
= g_strsplit (item
, "::", 0);
3577 namespaces_length
= g_strv_length (namespaces
);
3579 if (namespaces_length
> 1)
3581 /* this is the case in which we have the case with
3584 namespace_name
= g_strdup (namespaces
[namespaces_length
- 2]);
3585 klass_name
= g_strdup (namespaces
[namespaces_length
- 1]);
3589 /* have a last check before setting namespace_name to null.
3590 * check whether the field_namespace is void or not.
3592 const GValue
*namespace_value
;
3593 const gchar
*tmp_namespace
;
3594 gchar
**tmp_namespace_array
= NULL
;
3595 gint tmp_namespace_length
;
3598 gda_data_model_get_value_at_col_name (data
,
3599 "field_namespace", i
);
3600 tmp_namespace
= g_value_get_string (namespace_value
);
3601 if (tmp_namespace
!= NULL
)
3603 tmp_namespace_array
= g_strsplit (tmp_namespace
, "::", 0);
3604 tmp_namespace_length
= g_strv_length (tmp_namespace_array
);
3606 if (tmp_namespace_length
> 0)
3608 g_strdup (tmp_namespace_array
3609 [tmp_namespace_length
- 1]);
3611 namespace_name
= NULL
;
3615 namespace_name
= NULL
;
3618 klass_name
= g_strdup (namespaces
[namespaces_length
- 1]);
3620 g_strfreev (tmp_namespace_array
);
3623 g_strfreev (namespaces
);
3625 /* get the derived_klass_id. It should be the
3626 * symbol_referer_id field into __tmp_heritage_scope table
3628 if ((value
= (GValue
*) gda_data_model_get_value_at (data
,
3631 derived_klass_id
= g_value_get_int (value
);
3635 derived_klass_id
= 0;
3638 /* ok, search for the symbol_id of the base class */
3639 if (namespace_name
== NULL
)
3643 value1
= gda_value_new (G_TYPE_STRING
);
3644 g_value_set_string (value1
, klass_name
);
3646 if ((base_klass_id
=
3647 sdb_engine_get_table_id_by_unique_name (dbe
,
3648 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME
,
3652 gda_value_free (value1
);
3655 gda_value_free (value1
);
3660 when Libgda will parse correctly the PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME_AND_NAMESPACE
3661 query please uncomment this section and let the prepared statements do their
3667 value1 = gda_value_new (G_TYPE_STRING);
3668 g_value_set_string (value1, klass_name);
3670 value2 = gda_value_new (G_TYPE_STRING);
3671 g_value_set_string (value2, namespace_name);
3673 DEBUG_PRINT ("value1 : %s value2 : %s", klass_name, namespace_name);
3674 if ((base_klass_id =
3675 sdb_engine_get_table_id_by_unique_name2 (dbe,
3676 PREP_QUERY_GET_SYMBOL_ID_BY_CLASS_NAME_AND_NAMESPACE,
3682 gda_value_free (value1);
3683 gda_value_free (value2);
3686 gda_value_free (value1);
3687 gda_value_free (value2);
3690 GdaDataModel
*base_data
;
3693 g_strdup_printf ("SELECT symbol_id FROM symbol JOIN scope ON "
3694 "symbol.scope_id=scope.scope_id JOIN sym_type ON "
3695 "scope.type_id=sym_type.type_id WHERE "
3696 "symbol.name='%s' AND scope.scope_name='%s' AND "
3697 "sym_type.type='namespace'",
3698 klass_name
, namespace_name
);
3701 sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
3702 gda_data_model_get_n_rows (base_data
) <= 0 )
3706 if (base_data
!= NULL
)
3707 g_object_unref (base_data
);
3712 value1
= (GValue
*)gda_data_model_get_value_at (base_data
, 0, 0);
3713 base_klass_id
= g_value_get_int (value1
);
3714 DEBUG_PRINT ("found base_klass_id %d", base_klass_id
);
3717 if (base_data
!= NULL
)
3718 g_object_unref (base_data
);
3721 g_free (namespace_name
);
3722 g_free (klass_name
);
3724 DEBUG_PRINT ("gonna sdb_engine_add_new_heritage with "
3725 "base_klass_id %d, derived_klass_id %d", base_klass_id
,
3727 sdb_engine_add_new_heritage (dbe
, base_klass_id
, derived_klass_id
);
3730 g_strfreev (inherits_list
);
3735 * Process the temporary table to update the symbols on scope and inheritance
3737 * *CALL THIS FUNCTION ONLY AFTER HAVING PARSED ALL THE TAGS ONCE*
3741 sdb_engine_second_pass_do (SymbolDBEngine
* dbe
)
3743 GdaObject
*query_result
;
3744 const GdaQuery
*query1
, *query2
, *query3
;
3746 /* prepare for scope second scan */
3748 sdb_engine_get_query_by_id (dbe
,
3749 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE
))
3752 g_warning ("query is null");
3756 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3757 gda_query_get_query_type ((GdaQuery
*) query1
))
3759 g_warning ("non parsed sql error");
3763 /* execute the query */
3764 query_result
= gda_query_execute ((GdaQuery
*) query1
, NULL
, FALSE
, NULL
);
3766 if (!GDA_IS_DATA_MODEL (query_result
) ||
3767 gda_data_model_get_n_rows (GDA_DATA_MODEL (query_result
)) <= 0)
3769 if (query_result
!= NULL
)
3770 g_object_unref (query_result
);
3771 query_result
= NULL
;
3775 sdb_engine_second_pass_update_scope (dbe
, GDA_DATA_MODEL (query_result
));
3778 if (query_result
!= NULL
)
3779 g_object_unref (query_result
);
3781 /* prepare for heritage second scan */
3783 sdb_engine_get_query_by_id (dbe
,
3784 PREP_QUERY_GET_ALL_FROM_TMP_HERITAGE_WITH_INHERITS
))
3787 g_warning ("query is null");
3791 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3792 gda_query_get_query_type ((GdaQuery
*) query2
))
3794 g_warning ("non parsed sql error");
3798 /* execute the query */
3799 query_result
= gda_query_execute ((GdaQuery
*) query2
, NULL
, FALSE
, NULL
);
3801 if (!GDA_IS_DATA_MODEL (query_result
) ||
3802 gda_data_model_get_n_rows (GDA_DATA_MODEL (query_result
)) <= 0)
3804 if (query_result
!= NULL
)
3805 g_object_unref (query_result
);
3806 query_result
= NULL
;
3810 sdb_engine_second_pass_update_heritage (dbe
, GDA_DATA_MODEL (query_result
));
3813 if (query_result
!= NULL
)
3814 g_object_unref (query_result
);
3816 /* clean tmp heritage table */
3818 sdb_engine_get_query_by_id (dbe
,
3819 PREP_QUERY_TMP_HERITAGE_DELETE_ALL
))
3822 g_warning ("query is null");
3826 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
3827 gda_query_get_query_type ((GdaQuery
*) query3
))
3829 g_warning ("non parsed sql error");
3833 /* execute the query */
3835 gda_query_execute ((GdaQuery
*) query3
, NULL
, FALSE
, NULL
);
3837 if (query_result
!= NULL
)
3838 g_object_unref (query_result
);
3841 /* base_prj_path can be NULL. In that case path info tag_entry will be taken
3842 * as an absolute path.
3843 * fake_file can be used when a buffer updating is being executed. In that
3844 * particular case both base_prj_path and tag_entry->file will be ignored.
3845 * fake_file is real_path of file on disk
3848 sdb_engine_add_new_symbol (SymbolDBEngine
* dbe
, tagEntry
* tag_entry
,
3849 const gchar
*base_prj_path
, const gchar
*fake_file
,
3850 gboolean sym_update
)
3853 CREATE TABLE symbol (symbol_id integer PRIMARY KEY AUTOINCREMENT,
3854 file_defined_id integer not null REFERENCES file (file_id),
3855 name varchar (256) not null,
3856 file_position integer,
3857 is_file_scope integer,
3858 signature varchar (256),
3859 scope_definition_id integer,
3861 type_id integer REFERENCES sym_type (type_id),
3862 kind_id integer REFERENCES sym_kind (sym_kind_id),
3863 access_kind_id integer REFERENCES sym_access (sym_access_id),
3864 implementation_kind_id integer REFERENCES sym_implementation
3868 SymbolDBEnginePriv
*priv
;
3869 const GdaQuery
*query
;
3870 GdaObject
*query_result
;
3871 GdaParameterList
*par_list
;
3872 GdaParameter
*param
;
3873 const gchar
*tmp_str
;
3874 gint table_id
, symbol_id
;
3875 gint file_defined_id
= 0;
3877 gint file_position
= 0;
3878 gint is_file_scope
= 0;
3879 gchar signature
[256];
3880 gint scope_definition_id
= 0;
3884 gint access_kind_id
= 0;
3885 gint implementation_kind_id
= 0;
3886 GValue
*value
, *value1
, *value2
, *value3
;
3887 gboolean sym_was_updated
= FALSE
;
3891 g_return_val_if_fail (dbe
!= NULL
, -1);
3894 /* keep it at 0 if sym_update == false */
3895 if (sym_update
== FALSE
)
3900 g_return_val_if_fail (tag_entry
!= NULL
, -1);
3902 value
= gda_value_new (G_TYPE_STRING
);
3903 if (base_prj_path
!= NULL
)
3905 /* in this case fake_file will be ignored. */
3907 /* we expect here an absolute path */
3908 g_value_set_string (value
,
3909 tag_entry
->file
+ strlen (base_prj_path
) );
3913 /* check whether the fake_file can substitute the tag_entry->file one */
3914 if (fake_file
== NULL
)
3915 g_value_set_string (value
, tag_entry
->file
);
3917 g_value_set_string (value
, fake_file
);
3920 if ((file_defined_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
3921 PREP_QUERY_GET_FILE_ID_BY_UNIQUE_NAME
,
3925 /* if we arrive here there should be some sync problems between the filenames
3926 * in database and the ones in the ctags files. We trust in db's ones,
3927 * so we'll just return here.
3929 g_warning ("sync problems between db and ctags filenames entries. "
3930 "File was %s (base_path: %s, fake_file: %s, tag_file: %s)",
3931 g_value_get_string (value
), base_prj_path
, fake_file
,
3933 gda_value_free (value
);
3938 /* parse the entry name */
3939 if (strlen (tag_entry
->name
) > sizeof (name
))
3941 DEBUG_PRINT ("fatal error when inserting symbol, name of symbol is too big.");
3942 gda_value_free (value
);
3947 memset (name
, 0, sizeof (name
));
3948 memcpy (name
, tag_entry
->name
, strlen (tag_entry
->name
));
3951 file_position
= tag_entry
->address
.lineNumber
;
3952 is_file_scope
= tag_entry
->fileScope
;
3954 memset (signature
, 0, sizeof (signature
));
3955 if ((tmp_str
= tagsField (tag_entry
, "signature")) != NULL
)
3957 if (strlen (tmp_str
) > sizeof (signature
))
3959 memcpy (signature
, tmp_str
, sizeof (signature
));
3963 memcpy (signature
, tmp_str
, strlen (tmp_str
));
3967 type_id
= sdb_engine_add_new_sym_type (dbe
, tag_entry
);
3970 /* scope_definition_id tells what scope this symbol defines
3971 * this call *MUST BE DONE AFTER* sym_type table population.
3973 scope_definition_id
= sdb_engine_add_new_scope_definition (dbe
, tag_entry
,
3976 /* the container scopes can be: union, struct, typeref, class, namespace etc.
3977 * this field will be parse in the second pass.
3981 kind_id
= sdb_engine_add_new_sym_kind (dbe
, tag_entry
);
3983 access_kind_id
= sdb_engine_add_new_sym_access (dbe
, tag_entry
);
3984 implementation_kind_id
=
3985 sdb_engine_add_new_sym_implementation (dbe
, tag_entry
);
3987 /* ok: was the symbol updated [at least on it's type_id/name]?
3988 * There are 3 cases:
3989 * #1. The symbol remain the same [at least on unique index key]. We will
3990 * perform only a simple update.
3991 * #2. The symbol has changed: at least on name/type/file. We will insert a
3992 * new symbol on table 'symbol'. Deletion of old one will take place
3993 * at a second stage, when a delete of all symbols with
3994 * 'tmp_flag = 0' will be done.
3995 * #3. The symbol has been deleted. As above it will be deleted at
3996 * a second stage because of the 'tmp_flag = 0'. Triggers will remove
3997 * also scope_ids and other things.
4000 value1
= gda_value_new (G_TYPE_STRING
);
4001 g_value_set_string (value1
, name
);
4003 value2
= gda_value_new (G_TYPE_INT
);
4004 g_value_set_int (value2
, file_defined_id
);
4006 value3
= gda_value_new (G_TYPE_INT
);
4007 g_value_set_int (value3
, type_id
);
4009 if ((symbol_id
= sdb_engine_get_table_id_by_unique_name3 (dbe
,
4010 PREP_QUERY_GET_SYMBOL_ID_BY_UNIQUE_INDEX_KEY
,
4013 "typeid", value3
)) <= 0)
4016 sym_was_updated
= FALSE
;
4018 gda_value_free (value1
);
4019 gda_value_free (value2
);
4020 gda_value_free (value3
);
4022 /* create specific query for a fresh new symbol */
4023 if ((query
= sdb_engine_get_query_by_id (dbe
, PREP_QUERY_SYMBOL_NEW
))
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");
4034 gda_value_free (value
);
4039 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
4041 g_warning ("par_list is NULL!\n");
4042 gda_value_free (value
);
4046 /* filedefid parameter */
4048 gda_parameter_list_find_param (par_list
, "filedefid")) == NULL
)
4050 g_warning ("param filedefid is NULL from pquery!");
4051 gda_value_free (value
);
4055 gda_value_reset_with_type (value
, G_TYPE_INT
);
4056 g_value_set_int (value
, file_defined_id
);
4057 gda_parameter_set_value (param
, value
);
4059 /* name parameter */
4060 if ((param
= gda_parameter_list_find_param (par_list
, "name")) == NULL
)
4062 g_warning ("param name is NULL from pquery!");
4063 gda_value_free (value
);
4067 gda_value_reset_with_type (value
, G_TYPE_STRING
);
4068 g_value_set_string (value
, name
);
4069 gda_parameter_set_value (param
, value
);
4071 /* typeid parameter */
4073 gda_parameter_list_find_param (par_list
, "typeid")) == NULL
)
4075 g_warning ("param typeid is NULL from pquery!");
4076 gda_value_free (value
);
4080 gda_value_reset_with_type (value
, G_TYPE_INT
);
4081 g_value_set_int (value
, type_id
);
4082 gda_parameter_set_value (param
, value
);
4087 sym_was_updated
= TRUE
;
4089 gda_value_free (value1
);
4090 gda_value_free (value2
);
4091 gda_value_free (value3
);
4093 /* create specific query for a fresh new symbol */
4094 if ((query
= sdb_engine_get_query_by_id (dbe
,
4095 PREP_QUERY_UPDATE_SYMBOL_ALL
))
4098 g_warning ("query is null");
4102 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4103 gda_query_get_query_type ((GdaQuery
*) query
))
4105 g_warning ("non parsed sql error");
4106 gda_value_free (value
);
4111 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
4113 g_warning ("par_list is NULL!\n");
4114 gda_value_free (value
);
4118 /* symbolid parameter */
4119 if ((param
= gda_parameter_list_find_param (par_list
, "symbolid"))
4122 g_warning ("param isfilescope is NULL from pquery!");
4123 gda_value_free (value
);
4127 gda_value_reset_with_type (value
, G_TYPE_INT
);
4128 g_value_set_int (value
, symbol_id
);
4129 gda_parameter_set_value (param
, value
);
4134 /* fileposition parameter */
4136 gda_parameter_list_find_param (par_list
, "fileposition")) == NULL
)
4138 g_warning ("param fileposition is NULL from pquery!");
4139 gda_value_free (value
);
4143 gda_value_reset_with_type (value
, G_TYPE_INT
);
4144 g_value_set_int (value
, file_position
);
4145 gda_parameter_set_value (param
, value
);
4148 /* isfilescope parameter */
4150 gda_parameter_list_find_param (par_list
, "isfilescope")) == NULL
)
4152 g_warning ("param isfilescope is NULL from pquery!");
4153 gda_value_free (value
);
4157 gda_value_reset_with_type (value
, G_TYPE_INT
);
4158 g_value_set_int (value
, is_file_scope
);
4159 gda_parameter_set_value (param
, value
);
4161 /* signature parameter */
4162 if ((param
= gda_parameter_list_find_param (par_list
, "signature")) == NULL
)
4164 g_warning ("param signature is NULL from pquery!");
4165 gda_value_free (value
);
4169 gda_value_reset_with_type (value
, G_TYPE_STRING
);
4170 g_value_set_string (value
, signature
);
4171 gda_parameter_set_value (param
, value
);
4173 /* scopedefinitionid parameter */
4175 gda_parameter_list_find_param (par_list
, "scopedefinitionid")) == NULL
)
4177 g_warning ("param scopedefinitionid is NULL from pquery!");
4178 gda_value_free (value
);
4182 gda_value_reset_with_type (value
, G_TYPE_INT
);
4183 g_value_set_int (value
, scope_definition_id
);
4184 gda_parameter_set_value (param
, value
);
4186 /* scopeid parameter */
4187 if ((param
= gda_parameter_list_find_param (par_list
, "scopeid")) == NULL
)
4189 g_warning ("param scopeid is NULL from pquery!");
4190 gda_value_free (value
);
4194 gda_value_reset_with_type (value
, G_TYPE_INT
);
4195 g_value_set_int (value
, scope_id
);
4196 gda_parameter_set_value (param
, value
);
4198 /* kindid parameter */
4199 if ((param
= gda_parameter_list_find_param (par_list
, "kindid")) == NULL
)
4201 g_warning ("param kindid is NULL from pquery!");
4202 gda_value_free (value
);
4206 gda_value_reset_with_type (value
, G_TYPE_INT
);
4207 g_value_set_int (value
, kind_id
);
4208 gda_parameter_set_value (param
, value
);
4210 /* accesskindid parameter */
4212 gda_parameter_list_find_param (par_list
, "accesskindid")) == NULL
)
4214 g_warning ("param accesskindid is NULL from pquery!");
4215 gda_value_free (value
);
4219 gda_value_reset_with_type (value
, G_TYPE_INT
);
4220 g_value_set_int (value
, access_kind_id
);
4221 gda_parameter_set_value (param
, value
);
4223 /* implementationkindid parameter */
4225 gda_parameter_list_find_param (par_list
,
4226 "implementationkindid")) == NULL
)
4228 g_warning ("param implementationkindid is NULL from pquery!");
4229 gda_value_free (value
);
4233 gda_value_reset_with_type (value
, G_TYPE_INT
);
4234 g_value_set_int (value
, implementation_kind_id
);
4235 gda_parameter_set_value (param
, value
);
4237 /* updateflag parameter */
4239 gda_parameter_list_find_param (par_list
, "updateflag")) == NULL
)
4241 g_warning ("param updateflag is NULL from pquery!");
4242 gda_value_free (value
);
4246 gda_value_reset_with_type (value
, G_TYPE_INT
);
4247 g_value_set_int (value
, update_flag
);
4248 gda_parameter_set_value (param
, value
);
4249 gda_value_free (value
);
4251 /* execute the query with parametes just set */
4253 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
4255 if (sym_was_updated
== FALSE
)
4257 if (query_result
!= NULL
)
4259 table_id
= sdb_engine_get_last_insert_id (dbe
);
4260 g_object_unref (query_result
);
4262 /* This is a wrong place to emit the symbol-updated signal. Infact
4263 * db is in a inconsistent state, e.g. inheritance references are still
4265 * So add the symbol id into a queue that will be parsed once and emitted.
4267 g_async_queue_push (priv
->inserted_symbols_id
, (gpointer
) table_id
);
4276 if (query_result
!= NULL
)
4278 table_id
= symbol_id
;
4279 g_object_unref (query_result
);
4281 /* This is a wrong place to emit the symbol-updated signal. Infact
4282 * db is in a inconsistent state, e.g. inheritance references are still
4284 * So add the symbol id into a queue that will be parsed once and emitted.
4286 g_async_queue_push (priv
->updated_symbols_id
, (gpointer
) table_id
);
4294 /* before returning the table_id we have to fill some infoz on temporary tables
4295 * so that in a second pass we can parse also the heritage and scope fields.
4298 sdb_engine_add_new_tmp_heritage_scope (dbe
, tag_entry
, table_id
);
4304 * Select * from __tmp_removed and emits removed signals.
4307 sdb_engine_detects_removed_ids (SymbolDBEngine
*dbe
)
4309 const GdaQuery
*query
, *query2
;
4310 GdaObject
*query_result
;
4311 SymbolDBEnginePriv
*priv
;
4314 g_return_if_fail (dbe
!= NULL
);
4318 /* ok, now we should read from __tmp_removed all the symbol ids which have
4319 * been removed, and emit a signal
4321 if ((query
= sdb_engine_get_query_by_id (dbe
,
4322 PREP_QUERY_GET_REMOVED_IDS
))
4325 g_warning ("query is null");
4329 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4330 gda_query_get_query_type ((GdaQuery
*) query
))
4332 g_warning ("non parsed sql error");
4336 query_result
= gda_query_execute ((GdaQuery
*) query
, NULL
, FALSE
,
4339 if (GDA_IS_DATA_MODEL (query_result
))
4341 if ((num_rows
= gda_data_model_get_n_rows (GDA_DATA_MODEL (query_result
))) <= 0)
4343 DEBUG_PRINT ("sdb_engine_detects_removed_ids (): nothing to remove");
4344 g_object_unref (query_result
);
4350 if (query_result
!= NULL
)
4351 g_object_unref (query_result
);
4355 /* get and parse the results. */
4356 for (i
= 0; i
< num_rows
; i
++)
4360 val
= gda_data_model_get_value_at (GDA_DATA_MODEL (query_result
), 0, i
);
4361 tmp
= g_value_get_int (val
);
4363 DEBUG_PRINT ("EMITTING symbol-removed");
4364 g_async_queue_push (priv
->signals_queue
, (gpointer
)(SYMBOL_REMOVED
+ 1));
4365 g_async_queue_push (priv
->signals_queue
, (gpointer
)tmp
);
4368 g_object_unref (query_result
);
4370 /* let's clean the tmp_table */
4371 if ((query2
= sdb_engine_get_query_by_id (dbe
,
4372 PREP_QUERY_TMP_REMOVED_DELETE_ALL
))
4375 g_warning ("query is null");
4379 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4380 gda_query_get_query_type ((GdaQuery
*) query2
))
4382 g_warning ("non parsed sql error");
4388 gda_query_execute ((GdaQuery
*) query2
, NULL
, FALSE
, NULL
);
4392 g_object_unref (query_result
);
4397 * WARNING: do not use this function thinking that it would do a scan of symbols
4398 * too. Use symbol_db_engine_update_files_symbols () instead. This one will set
4399 * up some things on db, like removing the 'old' files which have not been
4403 sdb_engine_update_file (SymbolDBEngine
* dbe
, const gchar
* file_on_db
)
4405 const GdaQuery
*query
;
4406 GdaObject
*query_result
;
4408 GdaParameterList
*par_list
;
4409 GdaParameter
*param
;
4411 SymbolDBEnginePriv
*priv
;
4413 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
4417 if (symbol_db_engine_is_project_opened (dbe
, priv
->project_name
) == FALSE
)
4419 g_warning ("project is not opened");
4423 /* if we're updating symbols we must do some other operations on db
4424 * symbols, like remove the ones which don't have an update_flag = 1
4428 /* good. Go on with removing of old symbols, marked by a
4432 /* FIXME: libgda 3.0 doesn't have support for JOIN keyword at all on
4433 * prepared statements.
4434 * Said this we cannot expect to run queries on a really performant
4438 /* Triggers will take care of updating/deleting connected symbols
4439 * tuples, like sym_kind, sym_type etc */
4440 query_str
= g_strdup_printf ("DELETE FROM symbol WHERE "
4441 "file_defined_id = (SELECT file_id FROM file "
4442 "WHERE file_path = \"%s\") AND update_flag = 0",
4445 sdb_engine_execute_non_select_sql (dbe
, query_str
);
4448 /* emits removed symbols signals */
4449 sdb_engine_detects_removed_ids (dbe
);
4451 /* reset the update_flag to 0 */
4452 query_str
= g_strdup_printf ("UPDATE symbol SET update_flag = 0 "
4453 "WHERE file_defined_id = (SELECT file_id FROM file WHERE "
4454 "file_path = \"%s\")", file_on_db
);
4456 sdb_engine_execute_non_select_sql (dbe
, query_str
);
4459 /* last but not least, update the file analize_time */
4460 if ((query
= sdb_engine_get_query_by_id (dbe
,
4461 PREP_QUERY_UPDATE_FILE_ANALIZE_TIME
))
4464 g_warning ("query is null");
4468 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4469 gda_query_get_query_type ((GdaQuery
*) query
))
4471 g_warning ("non parsed sql error");
4475 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
4477 g_warning ("par_list is NULL!\n");
4481 /* filepath parameter */
4482 if ((param
= gda_parameter_list_find_param (par_list
, "filepath")) == NULL
)
4484 g_warning ("param filepath is NULL from pquery!");
4488 value
= gda_value_new (G_TYPE_STRING
);
4489 g_value_set_string (value
, file_on_db
);
4490 gda_parameter_set_value (param
, value
);
4492 gda_value_free (value
);
4494 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
4497 g_object_unref (query_result
);
4503 * @param data is a GPtrArray *files_to_scan
4504 * It will be freed when this callback will be called.
4507 on_scan_update_files_symbols_end (SymbolDBEngine
* dbe
, GPtrArray
* data
)
4509 SymbolDBEnginePriv
*priv
;
4510 GPtrArray
*files_to_scan
;
4513 DEBUG_PRINT ("on_scan_update_files_symbols_end ();");
4515 g_return_if_fail (dbe
!= NULL
);
4516 g_return_if_fail (data
!= NULL
);
4519 files_to_scan
= (GPtrArray
*) data
;
4521 for (i
= 0; i
< files_to_scan
->len
; i
++)
4523 gchar
*node
= (gchar
*) g_ptr_array_index (files_to_scan
, i
);
4525 /* clean the db from old un-updated with the last update step () */
4526 if (sdb_engine_update_file (dbe
, node
+
4527 strlen (priv
->data_source
)) == FALSE
)
4529 g_warning ("Error processing file %s", node
+
4530 strlen (priv
->data_source
) );
4536 g_signal_handlers_disconnect_by_func (dbe
, on_scan_update_files_symbols_end
,
4539 /* free the GPtrArray. */
4540 g_ptr_array_free (files_to_scan
, TRUE
);
4541 data
= files_to_scan
= NULL
;
4546 * Update symbols of saved files.
4547 * @note WARNING: files_path and it's contents will be freed on
4548 * on_scan_update_files_symbols_end () callback.
4551 symbol_db_engine_update_files_symbols (SymbolDBEngine
* dbe
, const gchar
* project
,
4552 GPtrArray
* files_path
,
4553 gboolean update_prj_analize_time
)
4555 SymbolDBEnginePriv
*priv
;
4559 DEBUG_PRINT ("symbol_db_engine_update_files_symbols ()");
4560 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
4561 g_return_val_if_fail (project
!= NULL
, FALSE
);
4563 if (symbol_db_engine_is_project_opened (dbe
, project
) == FALSE
)
4565 g_warning ("project is not opened");
4569 /* data will be freed when callback will be called. The signal will be
4570 * disconnected too, don't worry about disconneting it by hand.
4572 g_signal_connect (G_OBJECT (dbe
), "scan-end",
4573 G_CALLBACK (on_scan_update_files_symbols_end
), files_path
);
4575 sdb_engine_scan_files_1 (dbe
, files_path
, NULL
, TRUE
);
4577 /* if true, we'll update the project scanning time too.
4578 * warning: project time scanning won't could be set before files one.
4579 * This why we'll fork the process calling sdb_engine_scan_files ()
4581 if (update_prj_analize_time
== TRUE
)
4583 const GdaQuery
*query
;
4584 GdaObject
*query_result
;
4585 GdaParameterList
*par_list
;
4586 GdaParameter
*param
;
4589 /* and the project analize_time */
4590 if ((query
= sdb_engine_get_query_by_id (dbe
,
4591 PREP_QUERY_UPDATE_PROJECT_ANALIZE_TIME
))
4594 g_warning ("query is null");
4598 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4599 gda_query_get_query_type ((GdaQuery
*) query
))
4601 g_warning ("non parsed sql error");
4606 gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
4608 g_warning ("par_list is NULL!\n");
4612 /* prjname parameter */
4613 if ((param
= gda_parameter_list_find_param (par_list
, "prjname"))
4616 g_warning ("param prjname is NULL from pquery!");
4620 value
= gda_value_new (G_TYPE_STRING
);
4621 g_value_set_string (value
, priv
->project_name
);
4622 gda_parameter_set_value (param
, value
);
4624 gda_value_free (value
);
4626 DEBUG_PRINT ("updating project analize_time");
4628 gda_query_execute ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
4631 g_object_unref (query_result
);
4637 /* Update symbols of the whole project. It scans all file symbols etc.
4638 * FIXME: libgda does not support nested prepared queries like
4639 * PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_NAME. When it will do please
4640 * remember to update this function.
4643 symbol_db_engine_update_project_symbols (SymbolDBEngine
*dbe
, const gchar
*project
)
4645 const GdaQuery
*query
;
4646 GdaParameterList
*par_list
;
4647 GdaParameter
*param
;
4649 GdaObject
*query_result
;
4653 GPtrArray
*files_to_scan
;
4654 SymbolDBEnginePriv
*priv
;
4657 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
4658 if (symbol_db_engine_is_project_opened (dbe
, project
) == FALSE
)
4660 g_warning ("project is not opened");
4666 value
= gda_value_new (G_TYPE_STRING
);
4667 g_value_set_string (value
, project
);
4669 /* get project id */
4670 if ((project_id
= sdb_engine_get_table_id_by_unique_name (dbe
,
4671 PREP_QUERY_GET_PROJECT_ID_BY_UNIQUE_NAME
,
4675 gda_value_free (value
);
4679 if ((query
= sdb_engine_get_query_by_id (dbe
,
4680 PREP_QUERY_GET_ALL_FROM_FILE_BY_PROJECT_ID
))
4683 g_warning ("query is null");
4684 gda_value_free (value
);
4688 if (GDA_QUERY_TYPE_NON_PARSED_SQL
==
4689 gda_query_get_query_type ((GdaQuery
*) query
))
4691 g_warning ("non parsed sql error");
4692 gda_value_free (value
);
4696 if ((par_list
= gda_query_get_parameter_list ((GdaQuery
*) query
)) == NULL
)
4698 g_warning ("par_list is NULL!\n");
4699 gda_value_free (value
);
4703 /* prjid parameter */
4704 if ((param
= gda_parameter_list_find_param (par_list
, "prjid")) == NULL
)
4706 g_warning ("param prjname is NULL from pquery!");
4710 gda_value_reset_with_type (value
, G_TYPE_INT
);
4711 g_value_set_int (value
, project_id
);
4712 gda_parameter_set_value (param
, value
);
4714 /* execute the query with parametes just set */
4715 query_result
= gda_query_execute
4716 ((GdaQuery
*) query
, par_list
, FALSE
, NULL
);
4718 if (!GDA_IS_DATA_MODEL (query_result
) ||
4719 (num_rows
= gda_data_model_get_n_rows (GDA_DATA_MODEL (query_result
))) <= 0)
4721 g_message ("no rows");
4722 if (query_result
!= NULL
)
4723 g_object_unref (query_result
);
4724 query_result
= NULL
;
4727 /* we don't need it anymore */
4728 gda_value_free (value
);
4730 DEBUG_PRINT ("got gda_data_model_get_n_rows (GDA_DATA_MODEL(obj)) %d",
4733 /* initialize the array */
4734 files_to_scan
= g_ptr_array_new ();
4736 /* we can now scan each filename entry to check the last modification time. */
4737 for (i
= 0; i
< num_rows
; i
++)
4739 const GValue
*value
, *value1
;
4740 const gchar
*file_name
;
4741 gchar
*file_abs_path
;
4743 time_t db_file_time
;
4745 gchar
*abs_vfs_path
;
4746 GnomeVFSHandle
*handle
;
4749 gda_data_model_get_value_at_col_name (GDA_DATA_MODEL (query_result
),
4750 "file_path", i
)) == NULL
)
4755 /* build abs path. */
4756 file_name
= g_value_get_string (value
);
4757 if (priv
->data_source
!= NULL
)
4759 abs_vfs_path
= g_strdup_printf ("file://%s%s", priv
->data_source
,
4761 file_abs_path
= g_strdup_printf ("%s%s", priv
->data_source
,
4766 abs_vfs_path
= g_strdup_printf ("file://%s", file_name
);
4767 file_abs_path
= g_strdup (file_name
);
4770 GnomeVFSURI
*uri
= gnome_vfs_uri_new (abs_vfs_path
);
4771 GnomeVFSFileInfo
*file_info
= gnome_vfs_file_info_new ();
4773 /* retrieve data/time info */
4774 if (gnome_vfs_open_uri (&handle
, uri
,
4775 GNOME_VFS_OPEN_READ
| GNOME_VFS_OPEN_RANDOM
) !=
4778 g_message ("could not open URI %s", abs_vfs_path
);
4779 gnome_vfs_uri_unref (uri
);
4780 gnome_vfs_file_info_unref (file_info
);
4781 g_free (abs_vfs_path
);
4782 g_free (file_abs_path
);
4786 if (gnome_vfs_get_file_info_from_handle (handle
, file_info
,
4787 GNOME_VFS_FILE_INFO_DEFAULT
) !=
4790 g_message ("cannot get file info from handle");
4791 gnome_vfs_close (handle
);
4792 gnome_vfs_uri_unref (uri
);
4793 gnome_vfs_file_info_unref (file_info
);
4794 g_free (file_abs_path
);
4799 gda_data_model_get_value_at_col_name (GDA_DATA_MODEL (query_result
),
4800 "analize_time", i
)) == NULL
)
4805 /* weirdly we have a strange libgda behaviour here too.
4806 * as from ChangeLog GDA_TYPE_TIMESTAMP as SQLite does not impose a
4807 * known format for dates (there is no date datatype).
4808 * We have then to do some hackery to retrieve the date.
4810 date_string
= (gchar
*) g_value_get_string (value1
);
4812 DEBUG_PRINT ("processing for upating symbol %s", file_name
);
4813 DEBUG_PRINT ("date_string %s", date_string
);
4815 /* fill a struct tm with the date retrieved by the string. */
4816 /* string is something like '2007-04-18 23:51:39' */
4817 memset (&filetm
, 0, sizeof (struct tm
));
4818 filetm
.tm_year
= atoi (date_string
) - 1900;
4820 filetm
.tm_mon
= atoi (date_string
) - 1;
4822 filetm
.tm_mday
= atoi (date_string
);
4824 filetm
.tm_hour
= atoi (date_string
);
4826 filetm
.tm_min
= atoi (date_string
);
4828 filetm
.tm_sec
= atoi (date_string
);
4830 /* subtract one hour to the db_file_time. (why this?) */
4831 db_file_time
= mktime (&filetm
) - 3600;
4833 if (difftime (db_file_time
, file_info
->mtime
) <= 0)
4835 g_message ("to be added! : %s", file_name
);
4836 g_ptr_array_add (files_to_scan
, file_abs_path
);
4839 DEBUG_PRINT ("difftime %f", difftime (db_file_time, file_info->mtime));
4840 DEBUG_PRINT ("db_file_time %d - "
4841 "file_info->mtime %d "
4842 "file_info->ctime %d", db_file_time,
4843 file_info->mtime, file_info->ctime);
4845 gnome_vfs_close (handle
);
4846 gnome_vfs_uri_unref (uri
);
4847 gnome_vfs_file_info_unref (file_info
);
4848 g_free (abs_vfs_path
);
4849 /* no need to free file_abs_path, it's been added to files_to_scan */
4853 g_object_unref (query_result
);
4855 if (files_to_scan
->len
> 0)
4857 /* at the end let's the scanning function do its job */
4858 return symbol_db_engine_update_files_symbols (dbe
, project
,
4859 files_to_scan
, TRUE
);
4865 /* Remove a file, together with its symbols, from a project. */
4867 symbol_db_engine_remove_file (SymbolDBEngine
* dbe
, const gchar
* project
,
4871 SymbolDBEnginePriv
*priv
;
4873 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
4874 if (symbol_db_engine_is_project_opened (dbe
, project
) == FALSE
)
4876 g_warning ("project is not opened");
4882 if (strlen (file
) < strlen (priv
->data_source
))
4884 g_warning ("wrong file");
4888 /* Triggers will take care of updating/deleting connected symbols
4889 * tuples, like sym_kind, sym_type etc */
4890 query_str
= g_strdup_printf ("DELETE FROM file WHERE prj_id "
4891 "= (SELECT project_id FROM project WHERE project_name = '%s') AND "
4892 "file_path = '%s'", project
, file
+ strlen (priv
->data_source
));
4894 sdb_engine_execute_non_select_sql (dbe
, query_str
);
4897 /* emits removed symbols signals */
4898 sdb_engine_detects_removed_ids (dbe
);
4904 on_scan_update_buffer_end (SymbolDBEngine
* dbe
, gpointer data
)
4906 SymbolDBEnginePriv
*priv
;
4907 GPtrArray
*files_to_scan
;
4910 g_return_if_fail (dbe
!= NULL
);
4911 g_return_if_fail (data
!= NULL
);
4914 files_to_scan
= (GPtrArray
*) data
;
4916 DEBUG_PRINT ("files_to_scan->len %d", files_to_scan
->len
);
4918 for (i
= 0; i
< files_to_scan
->len
; i
++)
4920 gchar
*node
= (gchar
*) g_ptr_array_index (files_to_scan
, i
);
4922 DEBUG_PRINT ("processing updating for file [on disk] %s, "
4923 "passed to on_scan_update_buffer_end (): %s",
4924 node
, node
+ strlen (priv
->data_source
));
4926 /* will be emitted removed signals */
4927 if (sdb_engine_update_file (dbe
, node
+
4928 strlen (priv
->data_source
)) == FALSE
)
4930 g_warning ("Error processing file %s", node
);
4936 g_signal_handlers_disconnect_by_func (dbe
, on_scan_update_buffer_end
,
4939 /* free the GPtrArray. */
4940 DEBUG_PRINT ("free the files_to_scan");
4941 g_ptr_array_free (files_to_scan
, TRUE
);
4942 data
= files_to_scan
= NULL
;
4943 DEBUG_PRINT ("done");
4946 /* Update symbols of a file by a memory-buffer to perform a real-time updating
4948 * real_files_list: full path on disk to 'real file' to update. e.g.
4949 * /home/foouser/fooproject/src/main.c
4952 symbol_db_engine_update_buffer_symbols (SymbolDBEngine
* dbe
, const gchar
*project
,
4953 GPtrArray
* real_files_list
,
4954 const GPtrArray
* text_buffers
,
4955 const GPtrArray
* buffer_sizes
)
4957 SymbolDBEnginePriv
*priv
;
4960 DEBUG_PRINT ("symbol_db_engine_update_buffer_symbols ()");
4962 /* array that'll represent the /dev/shm/anjuta-XYZ files */
4963 GPtrArray
*temp_files
;
4964 GPtrArray
*real_files_on_db
;
4968 g_return_val_if_fail (priv
->db_connection
!= NULL
, FALSE
);
4969 g_return_val_if_fail (project
!= NULL
, FALSE
);
4970 g_return_val_if_fail (real_files_list
!= NULL
, FALSE
);
4971 g_return_val_if_fail (text_buffers
!= NULL
, FALSE
);
4972 g_return_val_if_fail (buffer_sizes
!= NULL
, FALSE
);
4974 if (symbol_db_engine_is_project_opened (dbe
, project
) == FALSE
)
4976 g_warning ("project is not opened");
4980 temp_files
= g_ptr_array_new();
4981 real_files_on_db
= g_ptr_array_new();
4983 /* obtain a GPtrArray with real_files on database */
4984 for (i
=0; i
< real_files_list
->len
; i
++)
4986 gchar
*new_node
= (gchar
*)g_ptr_array_index (real_files_list
, i
)
4987 + strlen(priv
->data_source
);
4988 /* DEBUG_PRINT ("real_file on db: %s", new_node);*/
4989 g_ptr_array_add (real_files_on_db
, g_strdup (new_node
));
4992 /* create a temporary file for each buffer */
4993 for (i
=0; i
< real_files_list
->len
; i
++)
4995 FILE *shared_mem_file
;
4996 const gchar
*temp_buffer
;
5000 gchar
*base_filename
;
5001 const gchar
*curr_real_file
;
5003 curr_real_file
= g_ptr_array_index (real_files_list
, i
);
5005 /* it's ok to have just the base filename to create the
5006 * target buffer one */
5007 base_filename
= g_filename_display_basename (curr_real_file
);
5009 temp_file
= g_strdup_printf ("/anjuta-%d-%ld-%s", getpid (),
5010 time (NULL
), base_filename
);
5011 g_free (base_filename
);
5013 if ((shared_mem_fd
=
5014 shm_open (temp_file
, O_CREAT
|O_RDWR
, S_IRUSR
|S_IWUSR
)) < 0)
5016 g_warning ("Error while trying to open a shared memory file. Be"
5017 "sure to have /dev/shm mounted with tmpfs");
5021 shared_mem_file
= fdopen (shared_mem_fd
, "w+b");
5023 temp_buffer
= g_ptr_array_index (text_buffers
, i
);
5024 temp_size
= (gint
)g_ptr_array_index (buffer_sizes
, i
);
5025 fwrite (temp_buffer
, sizeof(gchar
), temp_size
, shared_mem_file
);
5026 fflush (shared_mem_file
);
5027 fclose (shared_mem_file
);
5029 /* add the temp file to the array. */
5030 g_ptr_array_add (temp_files
, g_strdup_printf ("/dev/shm%s", temp_file
));
5035 /* data will be freed when callback will be called. The signal will be
5036 * disconnected too, don't worry about disconneting it by hand.
5038 g_signal_connect (G_OBJECT (dbe
), "scan-end",
5039 G_CALLBACK (on_scan_update_buffer_end
), real_files_list
);
5041 sdb_engine_scan_files_1 (dbe
, temp_files
, real_files_on_db
, TRUE
);
5043 /* let's free the temp_files array */
5044 for (i
=0; i
< temp_files
->len
; i
++)
5045 g_free (g_ptr_array_index (temp_files
, i
));
5047 g_ptr_array_free (temp_files
, TRUE
);
5049 /* and the real_files_on_db too */
5050 for (i
=0; i
< real_files_on_db
->len
; i
++)
5051 g_free (g_ptr_array_index (real_files_on_db
, i
));
5053 g_ptr_array_free (real_files_on_db
, TRUE
);
5060 symbol_db_engine_is_locked (SymbolDBEngine
* dbe
)
5062 SymbolDBEnginePriv
*priv
;
5064 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
5067 return priv
->scanning_status
;
5071 sdb_engine_walk_down_scope_path (SymbolDBEngine
*dbe
, const GPtrArray
* scope_path
)
5073 SymbolDBEnginePriv
*priv
;
5074 gint final_definition_id
;
5075 gint scope_path_len
;
5080 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
5083 scope_path_len
= scope_path
->len
;
5085 /* we'll return if the length is even or minor than 3 */
5086 if (scope_path_len
< 3 || scope_path_len
% 2 == 0)
5088 g_warning ("bad scope_path.");
5092 final_definition_id
= 0;
5093 for (i
=0; i
< scope_path_len
-1; i
= i
+ 2)
5095 const GValue
*value
;
5096 DEBUG_PRINT ("loop final_definition_id %d", final_definition_id
);
5098 query_str
= g_strdup_printf ("SELECT scope_definition_id FROM symbol "
5099 "WHERE scope_id = '%d' AND scope_definition_id = ("
5100 "SELECT scope.scope_id FROM scope "
5101 "INNER JOIN sym_type ON scope.type_id = sym_type.type_id "
5102 "WHERE sym_type.type = '%s' "
5103 "AND scope.scope_name = '%s'"
5104 ")", final_definition_id
, (gchar
*)g_ptr_array_index (scope_path
, i
),
5105 (gchar
*)g_ptr_array_index (scope_path
, i
+ 1));
5107 DEBUG_PRINT ("walk down query is %s", query_str
);
5109 if ( (data
= sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
5110 gda_data_model_get_n_rows (data
) <= 0 )
5118 value
= gda_data_model_get_value_at (data
, 0, 0);
5119 if (G_VALUE_HOLDS (value
, G_TYPE_INT
))
5121 final_definition_id
= g_value_get_int (value
);
5122 g_object_unref (data
);
5126 /* something went wrong. Our symbol cannot be retrieved coz of a
5129 final_definition_id
= -1;
5134 return final_definition_id
;
5137 /* Returns an iterator to the data retrieved from database.
5138 * The iterator, if not null, will contain a list of parent classes for the given
5140 * namespace_name can be NULL.
5142 SymbolDBEngineIterator
*
5143 symbol_db_engine_get_class_parents (SymbolDBEngine
*dbe
, const gchar
*klass_name
,
5144 const GPtrArray
*scope_path
)
5146 SymbolDBEnginePriv
*priv
;
5149 gint final_definition_id
;
5151 g_return_val_if_fail (dbe
!= NULL
, FALSE
);
5155 g_mutex_lock (priv
->mutex
);
5157 final_definition_id
= -1;
5158 if (scope_path
!= NULL
)
5159 final_definition_id
= sdb_engine_walk_down_scope_path (dbe
, scope_path
);
5161 /* FIXME: as always prepared queries of this complexity gives
5162 GDA_QUERY_TYPE_NON_PARSED_SQL error. */
5163 if (final_definition_id
> 0)
5165 query_str
= g_strdup_printf("SELECT symbol.symbol_id, symbol.name FROM heritage "
5166 "JOIN symbol ON heritage.symbol_id_base = symbol.symbol_id "
5167 "WHERE symbol_id_derived = ("
5168 "SELECT symbol_id FROM symbol "
5169 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id "
5170 "WHERE symbol.name = '%s' "
5171 "AND sym_kind.kind_name = 'class' "
5172 "AND symbol.scope_id = '%d'"
5173 ")", klass_name
, final_definition_id
);
5177 query_str
= g_strdup_printf("SELECT symbol.symbol_id, symbol.name FROM heritage "
5178 "JOIN symbol ON heritage.symbol_id_base = symbol.symbol_id "
5179 "WHERE symbol_id_derived = ("
5180 "SELECT symbol_id FROM symbol "
5181 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id "
5182 "WHERE symbol.name = '%s' "
5183 "AND sym_kind.kind_name = 'class' "
5187 DEBUG_PRINT ("get parents query: %s", query_str
);
5189 if ( (data
= sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
5190 gda_data_model_get_n_rows (data
) <= 0 )
5194 g_mutex_unlock (priv
->mutex
);
5201 g_mutex_unlock (priv
->mutex
);
5202 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5206 sdb_engine_prepare_symbol_info_sql (SymbolDBEngine
*dbe
, GString
*info_data
,
5207 GString
*join_data
, gint sym_info
)
5209 if (sym_info
& SYMINFO_FILE_PATH
||
5210 sym_info
& SYMINFO_LANGUAGE
||
5211 sym_info
& SYMINFO_PROJECT_NAME
||
5212 sym_info
& SYMINFO_FILE_IGNORE
||
5213 sym_info
& SYMINFO_FILE_INCLUDE
)
5215 info_data
= g_string_append (info_data
, ",file.file_path ");
5216 join_data
= g_string_append (join_data
, "LEFT JOIN file ON "
5217 "symbol.file_defined_id = file.file_id ");
5220 if (sym_info
& SYMINFO_LANGUAGE
)
5222 info_data
= g_string_append (info_data
, ",language.language_name ");
5223 join_data
= g_string_append (join_data
, "LEFT JOIN language ON "
5224 "file.lang_id = language.language_id ");
5227 if (sym_info
& SYMINFO_IMPLEMENTATION
)
5229 info_data
= g_string_append (info_data
, ",sym_implementation.implementation_name ");
5230 join_data
= g_string_append (join_data
, "LEFT JOIN sym_implementation ON "
5231 "symbol.implementation_kind_id = sym_implementation.sym_impl_id ");
5234 if (sym_info
& SYMINFO_ACCESS
)
5236 info_data
= g_string_append (info_data
, ",sym_access.access_name ");
5237 join_data
= g_string_append (join_data
, "LEFT JOIN sym_access ON "
5238 "symbol.access_kind_id = sym_access.access_kind_id ");
5241 if (sym_info
& SYMINFO_KIND
)
5243 info_data
= g_string_append (info_data
, ",sym_kind.kind_name ");
5244 join_data
= g_string_append (join_data
, "LEFT JOIN sym_kind ON "
5245 "symbol.kind_id = sym_kind.sym_kind_id ");
5248 if (sym_info
& SYMINFO_TYPE
|| sym_info
& SYMINFO_TYPE_NAME
)
5250 info_data
= g_string_append (info_data
, ",sym_type.type,"
5251 "sym_type.type_name ");
5252 join_data
= g_string_append (join_data
, "LEFT JOIN sym_type ON "
5253 "symbol.type_id = sym_type.type_id ");
5256 if (sym_info
& SYMINFO_PROJECT_NAME
||
5257 sym_info
& SYMINFO_FILE_IGNORE
||
5258 sym_info
& SYMINFO_FILE_INCLUDE
)
5260 info_data
= g_string_append (info_data
, ",project.project_name ");
5261 join_data
= g_string_append (join_data
, "LEFT JOIN project ON "
5262 "file.prj_id = project.project_id ");
5265 if (sym_info
& SYMINFO_FILE_IGNORE
)
5267 info_data
= g_string_append (info_data
, ",file_ignore.type AS file_ignore_type ");
5268 join_data
= g_string_append (join_data
, "LEFT JOIN ext_ignore ON "
5269 "ext_ignore.prj_id = project.project_id "
5270 "LEFT JOIN file_ignore ON "
5271 "ext_ignore.file_ign_id = file_ignore.file_ignore_id ");
5274 if (sym_info
& SYMINFO_FILE_INCLUDE
)
5276 info_data
= g_string_append (info_data
, ",file_include.type AS file_include_type ");
5277 join_data
= g_string_append (join_data
, "LEFT JOIN ext_include ON "
5278 "ext_include.prj_id = project.project_id "
5279 "LEFT JOIN file_include ON "
5280 "ext_include.file_incl_id = file_include.file_include_id ");
5283 /* TODO, or better.. TAKE A DECISION
5284 if (sym_info & SYMINFO_WORKSPACE_NAME)
5286 info_data = g_string_append (info_data, ",sym_access.access_name ");
5287 join_data = g_string_append (info_data, "LEFT JOIN sym_kind ON "
5288 "symbol.kind_id = sym_kind.sym_kind_id ");
5293 SymbolDBEngineIterator
*
5294 symbol_db_engine_get_global_members (SymbolDBEngine
*dbe
,
5295 const gchar
*kind
, gboolean group_them
,
5296 gint results_limit
, gint results_offset
,
5299 SymbolDBEnginePriv
*priv
;
5304 const gchar
*group_by_option
;
5306 gboolean limit_free
= FALSE
;
5308 gboolean offset_free
= FALSE
;
5310 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5314 g_mutex_lock (priv
->mutex
);
5316 /* check for an already flagged sym_info with KIND. SYMINFO_KIND on sym_info
5317 * is already contained into the default query infos.
5319 sym_info
= sym_info
& ~SYMINFO_KIND
;
5321 /* info_data contains the stuff after SELECT and befor FROM */
5322 info_data
= g_string_new ("");
5324 /* join_data contains the optionals joins to do to retrieve new data on other
5327 join_data
= g_string_new ("");
5329 /* fill info_data and join data with optional sql */
5330 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
5332 if (group_them
== TRUE
)
5334 group_by_option
= "GROUP BY symbol.name";
5338 group_by_option
= "";
5341 if (results_limit
> 0)
5343 limit
= g_strdup_printf ("LIMIT %d", results_limit
);
5347 if (results_offset
> 0)
5349 offset
= g_strdup_printf ("OFFSET %d", results_offset
);
5355 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, "
5356 "symbol.name, symbol.file_position, symbol.is_file_scope, "
5357 "symbol.signature, sym_kind.kind_name %s FROM symbol "
5358 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id %s "
5359 "WHERE symbol.scope_id <= 0 %s %s %s", info_data
->str
, join_data
->str
,
5360 group_by_option
, limit
, offset
);
5365 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5366 "symbol.file_position, "
5367 "symbol.is_file_scope, symbol.signature, sym_kind.kind_name %s FROM symbol "
5368 "JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id %s "
5369 "WHERE symbol.scope_id <= 0 "
5370 "AND sym_kind.kind_name = '%s' %s %s %s", info_data
->str
, join_data
->str
,
5371 kind
, group_by_option
, limit
, offset
);
5374 DEBUG_PRINT ("query is %s", query_str
);
5376 GdaCommand
*command
;
5377 command
= gda_command_new (query_str
, GDA_COMMAND_TYPE_SQL
,
5378 GDA_COMMAND_OPTION_STOP_ON_ERRORS
);
5380 if ( (data
= gda_connection_execute_select_command (priv
->db_connection
,
5381 command
, NULL
, NULL
)) == NULL
||
5382 gda_data_model_get_n_rows (data
) <= 0 )
5384 gda_command_free (command
);
5387 g_mutex_unlock (priv
->mutex
);
5391 // gda_data_model_dump (data, stdout);
5392 gda_command_free (command
);
5401 if ( (data
= sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
5402 gda_data_model_get_n_rows (data
) <= 0 )
5405 g_string_free (info_data
, FALSE
);
5406 g_string_free (join_data
, FALSE
);
5408 g_mutex_unlock (priv
->mutex
);
5411 // gda_data_model_dump (data, stdout);
5414 g_string_free (info_data
, FALSE
);
5415 g_string_free (join_data
, FALSE
);
5418 g_mutex_unlock (priv
->mutex
);
5419 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5424 * Sometimes it's useful going to query just with ids [and so integers] to have
5425 * a little speed improvement.
5427 SymbolDBEngineIterator
*
5428 symbol_db_engine_get_scope_members_by_symbol_id (SymbolDBEngine
*dbe
,
5429 gint scope_parent_symbol_id
,
5431 gint results_offset
,
5435 select b.* from symbol a, symbol b where a.symbol_id = 348 and
5436 b.scope_id = a.scope_definition_id;
5438 SymbolDBEnginePriv
*priv
;
5444 gboolean limit_free
= FALSE
;
5446 gboolean offset_free
= FALSE
;
5448 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5452 g_mutex_lock (priv
->mutex
);
5454 if (scope_parent_symbol_id
<= 0)
5457 g_mutex_unlock (priv
->mutex
);
5461 /* info_data contains the stuff after SELECT and befor FROM */
5462 info_data
= g_string_new ("");
5464 /* join_data contains the optionals joins to do to retrieve new data on other
5467 join_data
= g_string_new ("");
5469 /* fill info_data and join data with optional sql */
5470 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
5472 if (results_limit
> 0)
5474 limit
= g_strdup_printf ("LIMIT %d", results_limit
);
5478 if (results_offset
> 0)
5480 offset
= g_strdup_printf ("OFFSET %d", results_offset
);
5484 /* ok, beware that we use an 'alias hack' to accomplish compatibility with
5485 * sdb_engine_prepare_symbol_info_sql () function. In particular we called
5486 * the first joining table 'a', the second one 'symbol', where is the info we
5489 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5490 "symbol.file_position, "
5491 "symbol.is_file_scope, symbol.signature %s FROM symbol a, symbol symbol "
5492 "%s WHERE a.symbol_id = '%d' AND symbol.scope_id = a.scope_definition_id "
5493 "AND symbol.scope_id > 0 %s %s", info_data
->str
, join_data
->str
,
5494 scope_parent_symbol_id
,
5503 if ( (data
= sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
5504 gda_data_model_get_n_rows (data
) <= 0 )
5508 g_mutex_unlock (priv
->mutex
);
5513 g_string_free (info_data
, FALSE
);
5514 g_string_free (join_data
, FALSE
);
5517 g_mutex_unlock (priv
->mutex
);
5518 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5521 /* scope_path cannot be NULL.
5522 * scope_path will be something like "scope1_kind", "scope1_name", "scope2_kind",
5523 * "scope2_name", NULL
5525 SymbolDBEngineIterator
*
5526 symbol_db_engine_get_scope_members (SymbolDBEngine
*dbe
,
5527 const GPtrArray
* scope_path
, gint sym_info
)
5532 select * from symbol where scope_id = (
5533 select scope.scope_id from scope
5534 inner join sym_type on scope.type_id = sym_type.type_id
5535 where sym_type.type = 'class'
5536 and scope.scope_name = 'MyClass'
5539 select * from symbol where scope_id = (
5540 select scope.scope_id from scope
5541 inner join sym_type on scope.type_id = sym_type.type_id
5542 where sym_type.type = 'struct'
5543 and scope.scope_name = '_faa_1');
5546 es. scope_path = First, namespace, Second, namespace, NULL,
5547 symbol_name = Second_1_class
5549 SymbolDBEnginePriv
*priv
;
5552 gint final_definition_id
;
5556 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5560 g_mutex_lock (priv
->mutex
);
5562 final_definition_id
= sdb_engine_walk_down_scope_path (dbe
, scope_path
);
5564 if (final_definition_id
<= 0)
5567 g_mutex_unlock (priv
->mutex
);
5571 /* info_data contains the stuff after SELECT and befor FROM */
5572 info_data
= g_string_new ("");
5574 /* join_data contains the optionals joins to do to retrieve new data on other
5577 join_data
= g_string_new ("");
5579 /* fill info_data and join data with optional sql */
5580 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
5582 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5583 "symbol.file_position, "
5584 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5585 "%s WHERE scope_id = '%d'", info_data
->str
, join_data
->str
,
5586 final_definition_id
);
5588 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
5590 if ( (data
= sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
5591 gda_data_model_get_n_rows (data
) <= 0 )
5595 g_mutex_unlock (priv
->mutex
);
5600 g_string_free (info_data
, FALSE
);
5601 g_string_free (join_data
, FALSE
);
5604 g_mutex_unlock (priv
->mutex
);
5605 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5608 /* Returns an iterator to the data retrieved from database.
5609 * It will be possible to get the scope specified by the line of the file.
5611 SymbolDBEngineIterator
*
5612 symbol_db_engine_get_current_scope (SymbolDBEngine
*dbe
, const gchar
* filename
,
5615 SymbolDBEnginePriv
*priv
;
5616 gchar
*file_escaped
;
5620 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5624 g_mutex_lock (priv
->mutex
);
5625 file_escaped
= g_strescape (filename
, NULL
);
5627 /* WARNING: probably there can be some problems with escaping file names here.
5628 * They should come already escaped as from project db.
5630 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5631 "symbol.file_position, "
5632 "symbol.is_file_scope, symbol.signature, MIN('%d' - symbol.file_position) "
5634 "JOIN file ON file_defined_id = file_id "
5635 "WHERE file.file_path = \"%s\" "
5636 "AND '%d' - symbol.file_position >= 0", (gint
)line
, file_escaped
,
5639 DEBUG_PRINT ("current_scope query is %s", query_str
);
5641 if ( (data
= sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
5642 gda_data_model_get_n_rows (data
) <= 0 )
5645 g_free (file_escaped
);
5647 g_mutex_unlock (priv
->mutex
);
5652 g_free (file_escaped
);
5655 g_mutex_unlock (priv
->mutex
);
5656 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5661 * @param file_path Full local file path, e.g. /home/user/foo/file.c
5663 SymbolDBEngineIterator
*
5664 symbol_db_engine_get_file_symbols (SymbolDBEngine
*dbe
,
5665 const gchar
*file_path
, gint sym_info
)
5667 SymbolDBEnginePriv
*priv
;
5673 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5674 g_return_val_if_fail (file_path
!= NULL
, NULL
);
5676 g_return_val_if_fail (priv
->data_source
!= NULL
, NULL
);
5679 g_mutex_lock (priv
->mutex
);
5680 /* check for an already flagged sym_info with FILE_PATH. SYMINFO_FILE_PATH on
5681 * sym_info is already contained into the default query infos.
5683 sym_info
= sym_info
& ~SYMINFO_FILE_PATH
;
5685 /* info_data contains the stuff after SELECT and befor FROM */
5686 info_data
= g_string_new ("");
5688 /* join_data contains the optionals joins to do to retrieve new data on other
5691 join_data
= g_string_new ("");
5693 /* fill info_data and join data with optional sql */
5694 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
5696 /* rember to do a file_path + strlen(priv->data_source): a project relative
5699 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5700 "symbol.file_position, "
5701 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5702 "JOIN file ON symbol.file_defined_id = file.file_id "
5703 "%s WHERE file.file_path = \"%s\"", info_data
->str
, join_data
->str
,
5704 file_path
+ strlen(priv
->data_source
));
5706 DEBUG_PRINT ("symbol_db_engine_get_file_symbols (): query is %s", query_str
);
5708 if ( (data
= sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
5709 gda_data_model_get_n_rows (data
) <= 0 )
5713 g_mutex_unlock (priv
->mutex
);
5718 g_string_free (info_data
, FALSE
);
5719 g_string_free (join_data
, FALSE
);
5722 g_mutex_unlock (priv
->mutex
);
5723 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5727 SymbolDBEngineIterator
*
5728 symbol_db_engine_get_symbol_info_by_id (SymbolDBEngine
*dbe
,
5729 gint sym_id
, gint sym_info
)
5731 SymbolDBEnginePriv
*priv
;
5737 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5741 g_mutex_lock (priv
->mutex
);
5743 /* info_data contains the stuff after SELECT and befor FROM */
5744 info_data
= g_string_new ("");
5746 /* join_data contains the optionals joins to do to retrieve new data on other
5749 join_data
= g_string_new ("");
5751 /* fill info_data and join data with optional sql */
5752 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
5754 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5755 "symbol.file_position, "
5756 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5757 "%s WHERE symbol.symbol_id = %d", info_data
->str
, join_data
->str
,
5760 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
5762 if ( (data
= sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
5763 gda_data_model_get_n_rows (data
) <= 0 )
5767 g_mutex_unlock (priv
->mutex
);
5772 g_string_free (info_data
, FALSE
);
5773 g_string_free (join_data
, FALSE
);
5776 g_mutex_unlock (priv
->mutex
);
5777 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5780 /* user must free the returned value */
5782 symbol_db_engine_get_full_local_path (SymbolDBEngine
*dbe
, const gchar
* file
)
5784 SymbolDBEnginePriv
*priv
;
5787 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5790 full_path
= g_strdup_printf ("%s%s", priv
->data_source
, file
);
5795 symbol_db_engine_get_file_db_path (SymbolDBEngine
*dbe
, const gchar
* full_local_file_path
)
5797 SymbolDBEnginePriv
*priv
;
5798 gchar
*relative_path
;
5800 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5803 g_return_val_if_fail (priv
->data_source
!= NULL
, NULL
);
5805 if (strlen (priv
->data_source
) >= strlen (full_local_file_path
))
5810 tmp
= full_local_file_path
+ strlen (priv
->data_source
);
5811 relative_path
= strdup (tmp
);
5813 return relative_path
;
5817 SymbolDBEngineIterator
*
5818 symbol_db_engine_find_symbol_by_name_pattern (SymbolDBEngine
*dbe
,
5819 const gchar
*name
, gint sym_info
)
5821 SymbolDBEnginePriv
*priv
;
5827 g_return_val_if_fail (dbe
!= NULL
, NULL
);
5831 g_mutex_lock (priv
->mutex
);
5833 /* info_data contains the stuff after SELECT and befor FROM */
5834 info_data
= g_string_new ("");
5836 /* join_data contains the optionals joins to do to retrieve new data on other
5839 join_data
= g_string_new ("");
5841 /* fill info_data and join data with optional sql */
5842 sdb_engine_prepare_symbol_info_sql (dbe
, info_data
, join_data
, sym_info
);
5844 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.name, "
5845 "symbol.file_position, "
5846 "symbol.is_file_scope, symbol.signature %s FROM symbol "
5847 "%s WHERE symbol.name LIKE \"%s%%\"", info_data
->str
, join_data
->str
,
5850 /* DEBUG_PRINT ("DYNAMIC query is %s", query_str);*/
5852 if ( (data
= sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
5853 gda_data_model_get_n_rows (data
) <= 0 )
5857 g_mutex_unlock (priv
->mutex
);
5862 g_string_free (info_data
, FALSE
);
5863 g_string_free (join_data
, FALSE
);
5866 g_mutex_unlock (priv
->mutex
);
5867 return (SymbolDBEngineIterator
*)symbol_db_engine_iterator_new (data
);
5871 * No iterator for now. We need the quickest query possible.
5872 * @param db_file Can be NULL. In that case there won't be any check on file.
5875 symbol_db_engine_get_parent_scope_id_by_symbol_id (SymbolDBEngine
*dbe
,
5876 gint scoped_symbol_id
,
5877 const gchar
* db_file
)
5880 select * from symbol where scope_definition_id = (
5881 select scope_id from symbol where symbol_id = 26
5884 SymbolDBEnginePriv
*priv
;
5887 const GValue
* value
;
5891 g_return_val_if_fail (dbe
!= NULL
, -1);
5895 g_mutex_lock (priv
->mutex
);
5897 if (db_file
== NULL
)
5899 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.file_defined_id, "
5900 "symbol.file_position, symbol.scope_id "
5902 "WHERE symbol.scope_definition_id = ( "
5903 "SELECT symbol.scope_id FROM symbol WHERE symbol.symbol_id = '%d') "
5904 "AND symbol.scope_definition_id > 0",
5909 query_str
= g_strdup_printf ("SELECT symbol.symbol_id, symbol.file_defined_id, "
5910 "symbol.file_position, symbol.scope_id "
5911 "FROM symbol JOIN file "
5912 "ON symbol.file_defined_id = file.file_id "
5913 "WHERE symbol.scope_definition_id = ( "
5914 "SELECT symbol.scope_id FROM symbol WHERE symbol.symbol_id = '%d') "
5915 "AND symbol.scope_definition_id > 0 "
5916 "AND file.file_path = '%s' ",
5921 /* DEBUG_PRINT ("symbol_db_engine_get_parent_scope_id_by_symbol_id() query is %s",
5924 if ( (data
= sdb_engine_execute_select_sql (dbe
, query_str
)) == NULL
||
5925 gda_data_model_get_n_rows (data
) <= 0 )
5929 g_mutex_unlock (priv
->mutex
);
5935 num_rows
= gda_data_model_get_n_rows (data
);
5937 /* Hey, we can go in trouble here. Imagine this situation:
5938 * We have two namespaces, 'Editor' and 'Entwickler'. Inside
5939 * them there are two classes with the same name, 'Preferences', hence
5942 * This is how the above query will result:
5944 * 324|31|Preferences|28|0||192|92|276|3|-1|-1|0
5945 * 365|36|Preferences|33|0||192|2|276|3|-1|-1|0
5947 * Say that 92 is 'Editor' scope, and '2' is 'Entwickler'. We're looking for the
5948 * latter, and so we know that the right answer is symbol_id 365.
5949 * 1. We'll store the symbold_id(s) and the scope_id(s) of both 324 and 365.
5950 * 2. We'll query the db to retrieve all the symbols written before our
5951 * scoped_symbol_id in the file where scoped_symbol_id is.
5952 * 3. Compare every symbol's scope_defintion_id retrieved on step 2 against
5953 * all the ones saved at point 1. The first match is our parent_scope symbol_id.
5958 gchar
*detailed_query
;
5960 GList
*candidate_parents
= NULL
;
5961 typedef struct _candidate_node
{
5966 GdaDataModel
*detailed_data
;
5968 for (i
=0; i
< num_rows
; i
++)
5970 candidate_node
*node
;
5971 const GValue
*tmp_value
, *tmp_value1
;
5973 node
= g_new0 (candidate_node
, 1);
5975 /* get the symbol_id from the former 'data' result set */
5976 tmp_value
= gda_data_model_get_value_at (data
, 0, i
);
5977 node
->symbol_id
= tmp_value
!= NULL
&& G_VALUE_HOLDS_INT (tmp_value
)
5978 ? g_value_get_int (tmp_value
) : -1;
5981 tmp_value1
= gda_data_model_get_value_at (data
, 3, i
);
5982 node
->scope_id
= tmp_value1
!= NULL
&& G_VALUE_HOLDS_INT (tmp_value1
)
5983 ? g_value_get_int (tmp_value1
) : -1;
5985 candidate_parents
= g_list_prepend (candidate_parents
, node
);
5988 detailed_query
= g_strdup_printf ("SELECT symbol.scope_definition_id FROM symbol WHERE "
5989 "file_defined_id = (SELECT file_defined_id FROM symbol WHERE symbol_id = %d) "
5990 "AND file_position < (SELECT file_position FROM symbol WHERE symbol_id = %d) "
5991 "ORDER BY file_position DESC", scoped_symbol_id
, scoped_symbol_id
);
5993 /* DEBUG_PRINT ("detailed_query %s", detailed_query);*/
5995 /* we should receive just ONE row. If it's > 1 than we have surely an
5998 if ( (detailed_data
=
5999 sdb_engine_execute_select_sql (dbe
, detailed_query
)) == NULL
||
6000 gda_data_model_get_n_rows (detailed_data
) < 0)
6002 g_free (detailed_query
);
6005 else /* ok we have a good result here */
6008 gboolean found
= FALSE
;
6009 gint parent_scope_definition_id
;
6010 gint found_symbol_id
= -1;
6011 candidate_node
*node
= NULL
;
6013 g_free (detailed_query
);
6015 for (j
=0; j
< gda_data_model_get_n_rows (detailed_data
); j
++)
6017 const GValue
*tmp_value
;
6020 tmp_value
= gda_data_model_get_value_at (detailed_data
, 0, j
);
6021 parent_scope_definition_id
= tmp_value
!= NULL
&& G_VALUE_HOLDS_INT (tmp_value
)
6022 ? g_value_get_int (tmp_value
) : -1;
6024 /* DEBUG_PRINT ("symbol_db_engine_get_parent_scope_id_by_symbol_id (): "
6025 "testing parent_scope_definition_id %d",
6026 parent_scope_definition_id);*/
6028 for (k
= 0; k
< g_list_length (candidate_parents
); k
++)
6030 node
= g_list_nth_data (candidate_parents
, k
);
6031 if (node
->scope_id
== parent_scope_definition_id
)
6034 found_symbol_id
= node
->symbol_id
;
6043 /* ok, right now we have node and parent_scope_id we searched for */
6044 /* DEBUG_PRINT ("symbol_db_engine_get_parent_scope_id_by_symbol_id (): "
6045 "FOUND parent %d!", found_symbol_id);*/
6046 res
= found_symbol_id
;
6050 g_object_unref (detailed_data
);
6052 for (i
=0; i
< g_list_length (candidate_parents
); i
++)
6054 g_free (g_list_nth_data (candidate_parents
, i
));
6056 g_list_free (candidate_parents
);
6060 value
= gda_data_model_get_value_at (data
, 0, 0);
6061 res
= value
!= NULL
&& G_VALUE_HOLDS_INT (value
)
6062 ? g_value_get_int (value
) : -1;
6064 g_object_unref (data
);
6067 g_mutex_unlock (priv
->mutex
);