Преглед на файлове

DB drivers: SQLite - create_database() and list_databases() implemented
PostgreSQL - list_databases() enabled


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@53597 15284696-431f-4ddb-bdfa-cd5b030d7da7

Martin Landa преди 12 години
родител
ревизия
03c1931405
променени са 4 файла, в които са добавени 229 реда и са изтрити 16 реда
  1. 4 4
      db/drivers/README
  2. 15 9
      db/drivers/postgres/listdb.c
  3. 39 3
      db/drivers/sqlite/db.c
  4. 171 0
      db/drivers/sqlite/listdb.c

+ 4 - 4
db/drivers/README

@@ -2,13 +2,13 @@ This directory contains drivers for the DBMI library.
 The driver functions are for internal usage.
 The driver functions are for internal usage.
 
 
 The DBMI API to be used for module programming is available in:
 The DBMI API to be used for module programming is available in:
-grass6/lib/db/
+lib/db/
 
 
 
 
 NOTE:
 NOTE:
 db__driver_* functions are implemented in a driver.  If some of them
 db__driver_* functions are implemented in a driver.  If some of them
 are not used or defined, the driver will use stub functions in
 are not used or defined, the driver will use stub functions in
-grass6/lib/db/stubs/
+lib/db/stubs/
 
 
 For some platforms like Cygwin, multiply defined symbols are not
 For some platforms like Cygwin, multiply defined symbols are not
 resolved in a way that UNIX does.  Even worse is that it is impossible
 resolved in a way that UNIX does.  Even worse is that it is impossible
@@ -23,6 +23,6 @@ directory, #include "dbdriver.h" from main.c, and execute init_dbdriver().
 
 
 Function pointers are defined in grass6/lib/db/dbmi_driver/dbstubs.h
 Function pointers are defined in grass6/lib/db/dbmi_driver/dbstubs.h
 This header file can be generated with
 This header file can be generated with
-grass6/lib/db/dbmi_driver/mk_dbstubs_h.sh
+lib/db/dbmi_driver/mk_dbstubs_h.sh
 
 
-Please read grass6/lib/db/README
+Please read lib/db/README

+ 15 - 9
db/drivers/postgres/listdb.c

@@ -7,7 +7,9 @@
   (>=v2). Read the file COPYING that comes with GRASS for details.
   (>=v2). Read the file COPYING that comes with GRASS for details.
   
   
   \author Radim Blazek
   \author Radim Blazek
+  \author Updated for GRASS 7 by Martin Landa <landa.martin gmail.com>
  */
  */
+
 #include <grass/dbmi.h>
 #include <grass/dbmi.h>
 #include <grass/glocale.h>
 #include <grass/glocale.h>
 #include "globals.h"
 #include "globals.h"
@@ -26,18 +28,22 @@ int db__driver_list_databases(dbString * dbpath, int npaths,
     *dbcount = 0;
     *dbcount = 0;
 
 
     /* TODO: the solution below is not good as user usually does not have permissions for "template1" */
     /* TODO: the solution below is not good as user usually does not have permissions for "template1" */
-    db_d_append_error(_("db_driver_list_databases() is not implemented"));
-    db_d_report_error();
-    return DB_FAILED;
+    /*    db_d_append_error(_("db_driver_list_databases() is not implemented"));
+          db_d_report_error();
+          return DB_FAILED;
+    */
 
 
-    if (npaths > 0) {
-	G_debug(3, "location: %s", db_get_string(dbpath));
-	if (parse_conn(db_get_string(dbpath), &pgconn) == DB_FAILED) {
-	    db_d_report_error();
-	    return DB_FAILED;
-	}
+    if (npaths < 1) {
+        db_d_append_error(_("No path given"));
+        db_d_report_error();
+        return DB_FAILED;
     }
     }
 
 
+    if (parse_conn(db_get_string(dbpath), &pgconn) == DB_FAILED) {
+        db_d_report_error();
+        return DB_FAILED;
+    }
+    
     G_debug(3, "host = %s, port = %s, options = %s, tty = %s",
     G_debug(3, "host = %s, port = %s, options = %s, tty = %s",
 	    pgconn.host, pgconn.port, pgconn.options, pgconn.tty);
 	    pgconn.host, pgconn.port, pgconn.options, pgconn.tty);
 
 

+ 39 - 3
db/drivers/sqlite/db.c

@@ -14,6 +14,7 @@
 
 
 #include <stdlib.h>
 #include <stdlib.h>
 #include <string.h>
 #include <string.h>
+#include <unistd.h>
 #include <grass/gis.h>
 #include <grass/gis.h>
 #include <grass/dbmi.h>
 #include <grass/dbmi.h>
 #include <grass/glocale.h>
 #include <grass/glocale.h>
@@ -31,7 +32,7 @@
  */
  */
 int db__driver_open_database(dbHandle * handle)
 int db__driver_open_database(dbHandle * handle)
 {
 {
-    char name2[2000];
+    char name2[GPATH_MAX];
     const char *name;
     const char *name;
 
 
     G_debug(3, "\ndb_driver_open_database()");
     G_debug(3, "\ndb_driver_open_database()");
@@ -81,8 +82,9 @@ int db__driver_open_database(dbHandle * handle)
     G_debug(2, "name2 = '%s'", name2);
     G_debug(2, "name2 = '%s'", name2);
 
 
     if (sqlite3_open(name2, &sqlite) != SQLITE_OK) {
     if (sqlite3_open(name2, &sqlite) != SQLITE_OK) {
-	db_d_append_error("%s %s",
-			  _("Unable to open database: "),
+	db_d_append_error("%s %s\n%s",
+			  _("Unable to open database:"),
+                          name2,
 			  (char *)sqlite3_errmsg(sqlite));
 			  (char *)sqlite3_errmsg(sqlite));
 	db_d_report_error();
 	db_d_report_error();
 	return DB_FAILED;
 	return DB_FAILED;
@@ -110,3 +112,37 @@ int db__driver_close_database(void)
 
 
     return DB_OK;
     return DB_OK;
 }
 }
+
+/**
+ * \brief Create new empty SQLite database.
+ *
+ * \param handle dbHandle
+
+ * \return DB_OK on success
+ * \return DB_FAILED on failure
+ */
+
+int db__driver_create_database(dbHandle *handle)
+{
+    const char *name;
+    name = db_get_handle_dbname(handle);
+    
+    G_debug(1, "db_create_database(): %s", name);
+
+    if (access(name, F_OK) == 0) {
+        db_d_append_error(_("Database <%s> already exists"), name);
+        db_d_report_error();
+        return DB_FAILED;
+    }
+    
+    if (sqlite3_open(name, &sqlite) != SQLITE_OK) {
+	db_d_append_error("%s %s\n%s",
+			  _("Unable to create database:"),
+                          name,
+			  (char *) sqlite3_errmsg(sqlite));
+	db_d_report_error();
+	return DB_FAILED;
+    }
+    
+    return DB_FAILED;
+}

+ 171 - 0
db/drivers/sqlite/listdb.c

@@ -0,0 +1,171 @@
+/*!
+  \file db/drivers/sqlite/listdb.c
+ 
+  \brief DBMI - Low Level SQLite database driver (list databases)
+  
+  This program is free software under the GNU General Public License
+  (>=v2). Read the file COPYING that comes with GRASS for details.
+  
+  \author  Martin Landa <landa.martin gmail.com>
+*/
+
+#include <dirent.h>
+#include <string.h>
+
+#include <grass/gis.h>
+#include <grass/dbmi.h>
+#include <grass/glocale.h>
+
+#include "globals.h"
+#include "proto.h"
+
+static int listdb(dbString*, int, dbHandle**, int *);
+static void freedb(char **, int);
+
+/*!
+  \brief List SQLite databases for given paths.
+
+  List all files with extension <b>.db</b> and it's possible to open
+  them as SQLite database.
+
+  \todo Do it better?
+  
+  \param path list of paths
+  \param npaths number of given paths (?)
+  \param[out] handles output dbHandles
+  \param[out] count number of output handles
+
+  \return DB_OK on success
+  \return DB_FAILED on failure
+*/
+int db__driver_list_databases(dbString* path, int npaths,
+                              dbHandle** handles, int *count)
+{
+    if (npaths < 1) {
+        db_d_append_error(_("No path given"));
+        db_d_report_error();
+        return DB_FAILED;
+    }
+
+    if (strcmp(db_get_string(path), "") == 0) {
+        /* current location */
+        char *cpath;
+        dbString spath;
+
+        *handles = NULL;
+        *count = 0;
+        
+        cpath = G_mapset_path();
+        
+        db_init_string(&spath);
+        db_set_string(&spath, cpath);
+        G_free(cpath);
+        
+        if (listdb(&spath, 1, handles, count) != DB_OK)
+            return DB_FAILED;
+    }
+    else {
+        if (listdb(path, npaths, handles, count) != DB_OK)
+            return DB_FAILED;
+    }
+    
+    return DB_OK;
+}
+
+/* list .db file in the given path
+   TODO: do it better?
+*/
+int listdb(dbString* path, int npaths,
+           dbHandle** handles, int *count)
+{
+    int i, hcount, len;
+    dbHandle *hlist;
+    char **dlist;
+    
+    DIR *dirp;
+    struct dirent *dp;
+
+    if (npaths < 0)
+        return DB_FAILED;
+    
+    hcount = 0;
+    G_debug(3, "path = %s", db_get_string(path));
+
+    /* count number of dbs */
+    dirp = opendir(db_get_string(path));
+    if (dirp == NULL) {
+        db_d_append_error(_("Unable to open directory '%s'"),
+                          db_get_string(path));
+        db_d_report_error();
+        return DB_FAILED;
+    }
+    
+    dlist = NULL;
+    while ((dp = readdir(dirp)) != NULL) {
+        if (dp->d_name[0] == '.')
+            continue;
+        len = strlen(dp->d_name) - 3;
+        /* try to open file as SQLite database */
+        if (len > 0 && 
+            G_strcasecmp(dp->d_name + len, ".db") == 0 && 
+            sqlite3_open(dp->d_name, &sqlite) == SQLITE_OK) {
+           
+            if (sqlite3_close(sqlite) == SQLITE_BUSY) {
+                db_d_append_error(_("SQLite database connection '%s' is still busy"),
+                                  dp->d_name);
+                continue;
+            }
+            hcount++;
+            dlist = (char **) G_realloc(dlist, hcount * sizeof(char *));
+            G_debug(3, "%s", dp->d_name);
+            dlist[hcount-1] = G_store(dp->d_name);
+        }
+    }
+    G_debug(1, "db count = %d", hcount);
+
+    /* allocate handles */
+    hlist = db_alloc_handle_array(hcount);
+    if (hlist == NULL) {
+        db_d_append_error(_("Out of memory"));
+        db_d_report_error();
+
+        freedb(dlist, hcount);
+        closedir(dirp);
+        
+        return DB_FAILED;
+    }
+
+    /* get db names */
+    for (i = 0; i < hcount; i++) {
+        db_init_handle(&hlist[i]);
+        if (db_set_handle(&hlist[i], dlist[i], NULL) != DB_OK) {
+            db_d_append_error(_("Unable to set handle"));
+            db_d_report_error();
+            
+            db_free_handle_array(hlist, hcount);
+            freedb(dlist, hcount);
+            closedir(dirp);
+            
+            return DB_FAILED;
+        }
+    }
+
+    freedb(dlist, hcount);
+    closedir(dirp);
+
+    *handles = hlist;
+    *count = hcount;
+
+    return DB_OK;
+}
+
+/* free allocated memory */
+static void freedb(char **dblist, int count)
+{
+    int i;
+
+    for(i = 0; i < count; i++)
+        G_free(dblist[i]);
+    
+    G_free(dblist);
+}