[anjuta] symbol-db: fixed bgo#599323 - symbol-db plugin can't create the symbol database



commit f26f887f84f48604eab71d21ae822acd6bbd3e76
Author: Massimo Corà <mcora src gnome org>
Date:   Sat Dec 19 02:16:35 2009 +0100

    symbol-db: fixed bgo#599323 - symbol-db plugin can't create the symbol database
    
    Added automatic db upgrade to version 230. It'll recreate db from scratch
    because of sym_kind table changed values.
    Some minor fixes and improvements in open_db () functions.
    Plugin on_project_root_added () code cleaning.

 plugins/symbol-db/Makefile.am              |    2 +-
 plugins/symbol-db/benchmark/benchmark.c    |    2 +-
 plugins/symbol-db/plugin.c                 |   56 +++++++++------
 plugins/symbol-db/symbol-db-engine-core.c  |  104 ++++++++++++++++-----------
 plugins/symbol-db/symbol-db-engine-core.h  |    8 ++-
 plugins/symbol-db/symbol-db-engine-priv.h  |    3 +-
 plugins/symbol-db/tables-from-1-to-228.sql |    1 -
 plugins/symbol-db/tables.sql               |   82 +++++++++++-----------
 8 files changed, 147 insertions(+), 111 deletions(-)
---
diff --git a/plugins/symbol-db/Makefile.am b/plugins/symbol-db/Makefile.am
index 9b94b6d..0a69c98 100644
--- a/plugins/symbol-db/Makefile.am
+++ b/plugins/symbol-db/Makefile.am
@@ -1,7 +1,7 @@
 SUBDIRS = images benchmark anjuta-tags test-queries
 
 symbol_db_datadir = $(anjuta_data_dir)
-symbol_db_data_DATA = tables.sql tables-from-1-to-228.sql
+symbol_db_data_DATA = tables.sql
 
 # Plugin UI file
 symbol_db_uidir = $(anjuta_ui_dir)
diff --git a/plugins/symbol-db/benchmark/benchmark.c b/plugins/symbol-db/benchmark/benchmark.c
index 2da9819..a972104 100644
--- a/plugins/symbol-db/benchmark/benchmark.c
+++ b/plugins/symbol-db/benchmark/benchmark.c
@@ -51,7 +51,7 @@ int main (int argc, char** argv)
 	
     engine = symbol_db_engine_new_full ("anjuta-tags", "benchmark-db");
   
-	if (!symbol_db_engine_open_db (engine, root_dir, root_dir))
+	if (symbol_db_engine_open_db (engine, root_dir, root_dir) == DB_OPEN_STATUS_FATAL)
 	{
 		g_message ("Could not open database: %s", root_dir);
 		return -1;
diff --git a/plugins/symbol-db/plugin.c b/plugins/symbol-db/plugin.c
index 8366671..f4eda91 100644
--- a/plugins/symbol-db/plugin.c
+++ b/plugins/symbol-db/plugin.c
@@ -1838,9 +1838,12 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
 		gchar *anjuta_cache_path;
 		/* open the connection to global db */
 		anjuta_cache_path = anjuta_util_get_user_cache_file_path (".", NULL);
-		symbol_db_engine_open_db (sdb_plugin->sdbe_globals, 
+		if (symbol_db_engine_open_db (sdb_plugin->sdbe_globals, 
 							  anjuta_cache_path, 
-							  PROJECT_GLOBALS);
+							  PROJECT_GLOBALS) == DB_OPEN_STATUS_FATAL)
+		{
+			g_error ("Opening global project under %s", anjuta_cache_path);
+		}
 		g_free (anjuta_cache_path);
 	
 		/* unref and recreate the sdbs object */
@@ -1894,27 +1897,32 @@ on_project_root_added (AnjutaPlugin *plugin, const gchar *name,
 		lang_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, 
 										  sources_array_free);
 
-		/* is it a fresh-new project? is it an imported project with 
-		 * no 'new' symbol-db database but the 'old' one symbol-browser? 
-		 */
-		if (symbol_db_engine_db_exists (sdb_plugin->sdbe_project, 
-										root_dir) == FALSE)
-		{
-			DEBUG_PRINT ("Project %s does not exist", root_dir);
-			needs_sources_scan = TRUE;
-			project_exist = FALSE;
-		}
-		else 
-		{
-			project_exist = TRUE;
-		}
-
 		/* we'll use the same values for db_directory and project_directory */
 		DEBUG_PRINT ("Opening db %s and project_dir %s", root_dir, root_dir);
-		if (symbol_db_engine_open_db (sdb_plugin->sdbe_project, root_dir, 
-										  root_dir) == FALSE)
+		gint open_status = symbol_db_engine_open_db (sdb_plugin->sdbe_project, root_dir, 
+										  root_dir);
+
+		/* is it a fresh-new project? is it an imported project with 
+		 * no 'new' symbol-db database but the 'old' one symbol-browser? 
+		 */		
+		switch (open_status)
 		{
-			g_error ("*** Error in opening db ***");
+			case DB_OPEN_STATUS_FATAL:
+				g_error ("*** Error in opening db ***");
+				return;
+				
+			case DB_OPEN_STATUS_NORMAL:
+				project_exist = TRUE;
+				break;
+
+			case DB_OPEN_STATUS_CREATE:
+			case DB_OPEN_STATUS_UPGRADE:
+				needs_sources_scan = TRUE;
+				project_exist = FALSE;
+				break;
+				
+			default:
+				break;
 		}
 			
 		/* if project did not exist add a new project */
@@ -2275,9 +2283,13 @@ symbol_db_activate (AnjutaPlugin *plugin)
 	
 	/* open it */
 	anjuta_cache_path = anjuta_util_get_user_cache_file_path (".", NULL);
-	symbol_db_engine_open_db (sdb_plugin->sdbe_globals, 
+	if (symbol_db_engine_open_db (sdb_plugin->sdbe_globals, 
 							  anjuta_cache_path, 
-							  PROJECT_GLOBALS);
+							  PROJECT_GLOBALS) == DB_OPEN_STATUS_FATAL)
+	{
+		g_error ("Opening global project under %s", anjuta_cache_path);
+	}
+	
 	g_free (anjuta_cache_path);
 	
 	/* create the object that'll manage the globals population */
diff --git a/plugins/symbol-db/symbol-db-engine-core.c b/plugins/symbol-db/symbol-db-engine-core.c
index 8915532..0b004f5 100644
--- a/plugins/symbol-db/symbol-db-engine-core.c
+++ b/plugins/symbol-db/symbol-db-engine-core.c
@@ -719,12 +719,6 @@ sdb_engine_disconnect_from_db (SymbolDBEngine * dbe)
 		g_object_unref (priv->sql_parser);
 	priv->sql_parser = NULL;
 	
-	g_free (priv->db_directory);
-	priv->db_directory = NULL;
-	
-	g_free (priv->project_directory);
-	priv->project_directory = NULL;
-	
 	return TRUE;
 }
 
@@ -2977,6 +2971,12 @@ symbol_db_engine_close_db (SymbolDBEngine *dbe)
 	g_thread_pool_free (priv->thread_pool, TRUE, TRUE);
 	priv->thread_pool = NULL;
 	ret = sdb_engine_disconnect_from_db (dbe);
+
+	g_free (priv->db_directory);
+	priv->db_directory = NULL;
+	
+	g_free (priv->project_directory);
+	priv->project_directory = NULL;	
 	
 	priv->thread_pool = g_thread_pool_new (sdb_engine_ctags_output_thread,
 										   dbe, THREADS_MAX_CONCURRENT,
@@ -3013,8 +3013,10 @@ sdb_engine_get_db_version (SymbolDBEngine *dbe)
 	return version_id;
 }
 
-static void
-sdb_engine_check_db_version_and_upgrade (SymbolDBEngine *dbe)
+static gboolean
+sdb_engine_check_db_version_and_upgrade (SymbolDBEngine *dbe, 
+                                         const gchar* db_file,
+                                         const gchar* cnc_string)
 {
 	SymbolDBEnginePriv *priv;
 	gint version;
@@ -3027,45 +3029,51 @@ sdb_engine_check_db_version_and_upgrade (SymbolDBEngine *dbe)
 	{
 		/* some error occurred */
 		g_warning ("No version of db detected. This can produce many errors.");
-		return;
+		return FALSE;
 	}
 	
 	/* FIXME: in the future versions, if the changes grow up, add a better 
 	 * automatic upgrading system 
 	 */
-	if (version < 228)
+	if (version < 230)
 	{
-		gchar *contents;
-		gchar *query;
-		gsize sizez;
-
-		DEBUG_PRINT	 ("Upgrading from version %d to 228", version);
+		DEBUG_PRINT	 ("Upgrading from version %d to 230", version);
 		
-		/* read the contents of the file */
-		if (g_file_get_contents (TABLES_SQL_1_TO_228, &contents, &sizez, NULL) == FALSE)
-		{
-			g_warning ("Something went wrong while trying to read %s",
-					TABLES_SQL_1_TO_228);
-			return;
+		/* we need a full recreation of db. Because of the sym_kind table
+		 * which changed its data but not its fields, we must recreate the
+		 * whole database.
+		 */
+
+		/* 1. disconnect from current db */
+		sdb_engine_disconnect_from_db (dbe);
+
+		/* 2. remove current db file */
+		GFile *gfile = g_file_new_for_path (db_file);
+		if (gfile != NULL) {
+			g_file_delete (gfile, NULL, NULL);
+			g_object_unref (gfile);
 		}
+		else 
+		{
+			g_warning ("Could not get the gfile");
+		}		
 
-		sdb_engine_execute_non_select_sql (dbe, contents);	
-		g_free (contents);		
-		
-		query = "UPDATE version SET sdb_version = "SYMBOL_DB_VERSION;
-		sdb_engine_execute_non_select_sql (dbe, query);
+		/* 3. reconnect */
+		sdb_engine_connect_to_db (dbe, cnc_string);
 
-		// go on with the update of all the symbols in project
-		symbol_db_engine_update_project_symbols (dbe, priv->project_directory, 
-		    TRUE);
-	}	
+		/* 4. create fresh new tables, indexes, triggers etc.  */			
+		sdb_engine_create_db_tables (dbe, TABLES_SQL);
+		return TRUE;
+	}
 	else
 	{
 		DEBUG_PRINT ("No need to upgrade.");
 	}
+
+	return FALSE;
 }
 
-gboolean
+gint
 symbol_db_engine_open_db (SymbolDBEngine * dbe, const gchar * base_db_path,
 						  const gchar * prj_directory)
 {
@@ -3073,6 +3081,7 @@ symbol_db_engine_open_db (SymbolDBEngine * dbe, const gchar * base_db_path,
 	gboolean needs_tables_creation = FALSE;
 	gchar *cnc_string;
 	gboolean connect_res;
+	gboolean ret_status = DB_OPEN_STATUS_NORMAL;
 
 	DEBUG_PRINT ("Opening project %s with base dir %s", 
 				 prj_directory, base_db_path);
@@ -3084,15 +3093,13 @@ symbol_db_engine_open_db (SymbolDBEngine * dbe, const gchar * base_db_path,
 
 	/* check whether the db filename already exists. If it's not the case
 	 * create the tables for the database. */
-	gchar *tmp_file = g_strdup_printf ("%s/%s.db", base_db_path,
+	gchar *db_file = g_strdup_printf ("%s/%s.db", base_db_path,
 									   priv->anjuta_db_file);
 
-	if (g_file_test (tmp_file, G_FILE_TEST_EXISTS) == FALSE)
+	if (g_file_test (db_file, G_FILE_TEST_EXISTS) == FALSE)
 	{
 		needs_tables_creation = TRUE;
 	}
-	g_free (tmp_file);
-
 
 	priv->db_directory = g_strdup (base_db_path);
 	
@@ -3105,28 +3112,41 @@ symbol_db_engine_open_db (SymbolDBEngine * dbe, const gchar * base_db_path,
 	DEBUG_PRINT ("Connecting to "
 				 "database with %s...", cnc_string);
 	connect_res = sdb_engine_connect_to_db (dbe, cnc_string);
-	g_free (cnc_string);
+	
 
 	if (connect_res == FALSE)
-		return FALSE;
+	{
+		g_free (db_file);
+		g_free (cnc_string);
+
+		ret_status = DB_OPEN_STATUS_FATAL;
+		return ret_status;
+	}
 	
 	if (needs_tables_creation == TRUE)
 	{
-		DEBUG_PRINT ("Creating tables: it needs tables...");
+		DEBUG_PRINT ("Creating tables...");
 		sdb_engine_create_db_tables (dbe, TABLES_SQL);
+		ret_status = DB_OPEN_STATUS_CREATE;
 	}
 	else 
 	{
 		/* check the version of the db. If it's old we should upgrade it */
-		sdb_engine_check_db_version_and_upgrade (dbe);
+		if (sdb_engine_check_db_version_and_upgrade (dbe, db_file, cnc_string) == TRUE)
+		{
+			ret_status = DB_OPEN_STATUS_UPGRADE;
+		}		
 	}
-
+	
 	sdb_engine_set_defaults_db_parameters (dbe);
 
 	/* normalize some tables */
 	sdb_engine_normalize_sym_type (dbe);
-		
-	return TRUE;
+
+	g_free (cnc_string);
+	g_free (db_file);
+	
+	return ret_status;
 }
 
 gchar *
diff --git a/plugins/symbol-db/symbol-db-engine-core.h b/plugins/symbol-db/symbol-db-engine-core.h
index d27ae33..162a1ef 100644
--- a/plugins/symbol-db/symbol-db-engine-core.h
+++ b/plugins/symbol-db/symbol-db-engine-core.h
@@ -92,7 +92,7 @@ symbol_db_engine_set_ctags_path (SymbolDBEngine *dbe,
 								  const gchar * ctags_path);
 
 /**
- * Open or create a new database at given directory. 
+ * Open, create or upgrade a database at given directory. 
  * Be sure to give a base_db_path with the ending '/' for directory.
  * @param base_db_path directory where .anjuta_sym_db.db will be stored. It can be
  *        different from project_directory
@@ -104,7 +104,11 @@ symbol_db_engine_set_ctags_path (SymbolDBEngine *dbe,
  *        src/file.c. In this way you can move around the project dir without dealing
  *        with relative paths.
  */
-gboolean 
+#define DB_OPEN_STATUS_FATAL		-1
+#define DB_OPEN_STATUS_NORMAL		0
+#define DB_OPEN_STATUS_CREATE		1
+#define DB_OPEN_STATUS_UPGRADE		2
+gint
 symbol_db_engine_open_db (SymbolDBEngine *dbe, const gchar* base_db_path,
 						  const gchar * prj_directory);
 
diff --git a/plugins/symbol-db/symbol-db-engine-priv.h b/plugins/symbol-db/symbol-db-engine-priv.h
index 1a082ea..124fdc0 100644
--- a/plugins/symbol-db/symbol-db-engine-priv.h
+++ b/plugins/symbol-db/symbol-db-engine-priv.h
@@ -41,10 +41,9 @@
 #define ANJUTA_DB_FILE	".anjuta_sym_db"
 
 /* if tables.sql changes or general db structure changes modify also the value here */
-#define SYMBOL_DB_VERSION	"228"
+#define SYMBOL_DB_VERSION	"230"
 
 #define TABLES_SQL			PACKAGE_DATA_DIR"/tables.sql"
-#define TABLES_SQL_1_TO_228	PACKAGE_DATA_DIR"/tables-from-1-to-228.sql"
 
 #define CTAGS_MARKER	"#_#\n"
 
diff --git a/plugins/symbol-db/tables.sql b/plugins/symbol-db/tables.sql
index 9540083..4560078 100644
--- a/plugins/symbol-db/tables.sql
+++ b/plugins/symbol-db/tables.sql
@@ -2,45 +2,54 @@
 -- FIXME: FOREIGN keys are now supported. schema should enforces them.
 -- Right now the support here is disabled.
 
+DROP TABLE IF EXISTS workspace;
 CREATE TABLE workspace (workspace_id integer PRIMARY KEY AUTOINCREMENT,
                         workspace_name varchar (50) not null unique,
                         analyse_time DATE
                         );
 
+DROP TABLE IF EXISTS project;
 CREATE TABLE project (project_id integer PRIMARY KEY AUTOINCREMENT,
                       project_name varchar (50) not null unique,
                       wrkspace_id integer REFERENCES workspace (workspace_id),
                       analyse_time DATE
                       );
-                    
+
+DROP TABLE IF EXISTS file_include;
 CREATE TABLE file_include (file_include_id integer PRIMARY KEY AUTOINCREMENT,
                            file_include_type varchar (10) not null unique
                            );
 
+DROP TABLE IF EXISTS ext_include;
 CREATE TABLE ext_include (prj_id integer REFERENCES project (project_id),
                           file_incl_id integer REFERENCES file_include (file_include_id),
                           PRIMARY KEY (prj_id, file_incl_id)
                           );
-                          
+
+DROP TABLE IF EXISTS file_ignore;
 CREATE TABLE file_ignore (file_ignore_id integer PRIMARY KEY AUTOINCREMENT,
                           file_ignore_type varchar (10) unique                          
                           );
 
+DROP TABLE IF EXISTS ext_ignore;
 CREATE TABLE ext_ignore (prj_id integer REFERENCES project (project_id),
                          file_ign_id integer REFERENCES file_ignore (file_ignore_id),
                          PRIMARY KEY (prj_id, file_ign_id)
                          );
-                         
+
+DROP TABLE IF EXISTS file;
 CREATE TABLE file (file_id integer PRIMARY KEY AUTOINCREMENT,
                    file_path TEXT not null unique,
                    prj_id integer REFERENCES project (projec_id),
                    lang_id integer REFERENCES language (language_id),
                    analyse_time DATE
                    );
-                   
+
+DROP TABLE IF EXISTS language;
 CREATE TABLE language (language_id integer PRIMARY KEY AUTOINCREMENT,
                        language_name varchar (50) not null unique);
 
+DROP TABLE IF EXISTS symbol;
 CREATE TABLE symbol (symbol_id integer PRIMARY KEY AUTOINCREMENT,
                      file_defined_id integer not null REFERENCES file (file_id),
                      name varchar (256) not null,
@@ -54,89 +63,82 @@ CREATE TABLE symbol (symbol_id integer PRIMARY KEY AUTOINCREMENT,
                      kind_id integer REFERENCES sym_kind (sym_kind_id),
                      access_kind_id integer REFERENCES sym_access (sym_access_id),
                      implementation_kind_id integer REFERENCES sym_implementation (sym_impl_id),
-					 update_flag integer default 0,
+                     update_flag integer default 0,
                      unique (name, file_defined_id, file_position)
                      );
-                     
+
+DROP TABLE IF EXISTS sym_type;
 CREATE TABLE sym_type (type_id integer PRIMARY KEY AUTOINCREMENT,
                    type_type varchar (256) not null,
                    type_name varchar (256) not null,
                    unique (type_type, type_name)
                    );
 
+DROP TABLE IF EXISTS sym_kind;
 CREATE TABLE sym_kind (sym_kind_id integer PRIMARY KEY AUTOINCREMENT,
                        kind_name varchar (50) not null unique
                        );
 
+DROP TABLE IF EXISTS sym_access;
 CREATE TABLE sym_access (access_kind_id integer PRIMARY KEY AUTOINCREMENT,
                          access_name varchar (50) not null unique
                          );
 
+DROP TABLE IF EXISTS sym_implementation;
 CREATE TABLE sym_implementation (sym_impl_id integer PRIMARY KEY AUTOINCREMENT,
                                  implementation_name varchar (50) not null unique
                                  );
 
+DROP TABLE IF EXISTS heritage;
 CREATE TABLE heritage (symbol_id_base integer REFERENCES symbol (symbol_id),
                        symbol_id_derived integer REFERENCES symbol (symbol_id),
                        PRIMARY KEY (symbol_id_base, symbol_id_derived)
                        );
-                       
+
+DROP TABLE IF EXISTS scope;
 CREATE TABLE scope (scope_id integer PRIMARY KEY AUTOINCREMENT,
                     scope_name varchar(256) not null,
                     type_id integer,
                     unique (scope_name, type_id)
                     );
 
+DROP TABLE IF EXISTS version;
 CREATE TABLE version (sdb_version numeric PRIMARY KEY);
 
+DROP TABLE IF EXISTS __tmp_heritage_scope;
 CREATE TABLE __tmp_heritage_scope (tmp_heritage_scope_id integer PRIMARY KEY AUTOINCREMENT,
-							symbol_referer_id integer not null,
-							field_inherits varchar(256),
-							field_struct varchar(256),
-							field_typeref varchar(256),
-							field_enum varchar(256),
-							field_union varchar(256),
-							field_class varchar(256),
-							field_namespace varchar(256)
-							);
-
+                            symbol_referer_id integer not null,
+                            field_inherits varchar(256),
+                            field_struct varchar(256),
+                            field_typeref varchar(256),
+                            field_enum varchar(256),
+                            field_union varchar(256),
+                            field_class varchar(256),
+                            field_namespace varchar(256)
+                            );
+
+DROP TABLE IF EXISTS __tmp_removed;
 CREATE TABLE __tmp_removed (tmp_removed_id integer PRIMARY KEY AUTOINCREMENT,
-							symbol_removed_id integer not null
-							);
-
--- test on 250 .c files.
--- all indexes disabled: 13.1 ms/symbol; after pragmas: 11.9
--- all indexes enabled: 14.3 ms/symbol
--- symbol_idx_1 enabled: 13.4 ms/symbol
--- unique keys (symbol_idx_2, scope_idx_2, file_idx_1, sym_type_idx_2): 13.3
--- symbol_idx_1, symbol_idx_3, symbol_idx_4, scope_idx_1, sym_type_idx_1: 13.9
-
---CREATE INDEX symbol_idx_1 ON symbol (name);
-
---not needed CREATE INDEX symbol_idx_2 ON symbol (name, file_defined_id, file_position);
+                            symbol_removed_id integer not null
+                            );
 
+DROP INDEX IF EXISTS symbol_idx_3;
 CREATE INDEX symbol_idx_3 ON symbol (name, file_defined_id, type_id);
 
+DROP INDEX IF EXISTS symbol_idx_4;
 CREATE INDEX symbol_idx_4 ON symbol (scope_id);
 
+DROP INDEX IF EXISTS symbol_idx_5;
 CREATE INDEX symbol_idx_5 ON symbol (type_id);
 
---CREATE INDEX scope_idx_1 ON scope (scope_name);
-
---not needed CREATE INDEX scope_idx_2 ON scope (scope_name, type_id);
-
---not needed CREATE INDEX file_idx_1 ON file (file_path);
-
---CREATE INDEX sym_type_idx_1 ON sym_type (type_type);
-
---not needed CREATE INDEX sym_type_idx_2 ON sym_type (type_type, type_name);
-
+DROP TRIGGER IF EXISTS delete_file_trg;
 CREATE TRIGGER delete_file_trg BEFORE DELETE ON file
 FOR EACH ROW
 BEGIN
 	DELETE FROM symbol WHERE file_defined_id = old.file_id;
 END;
 
+DROP TRIGGER IF EXISTS delete_symbol_trg;
 CREATE TRIGGER delete_symbol_trg BEFORE DELETE ON symbol
 FOR EACH ROW
 BEGIN



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]