1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
|
/**
* \file db.c
*
* \brief DBMI - Low Level SQLite database driver.
*
* This program is free software under the GNU General Public License
* (>=v2). Read the file COPYING that comes with GRASS for details.
*
* \author Radim Blazek
* \author Support for multiple connections by Markus Metz
*
* \date 2005-2011
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <grass/gis.h>
#include <grass/dbmi.h>
#include <grass/glocale.h>
#include "globals.h"
#include "proto.h"
/**
* \brief Open SQLite database.
*
* \param[in,out] handle database handle
*
* \return DB_FAILED on error
* \return DB_OK on success
*/
int db__driver_open_database(dbHandle *handle)
{
char name2[GPATH_MAX], *path;
const char *name;
char name3[GPATH_MAX + 14], *env_nolock;
int i;
G_debug(3, "\ndb_driver_open_database()");
name = db_get_handle_dbname(handle);
/* if name is empty use connection.databaseName */
if (strlen(name) == 0) {
dbConnection connection;
db_get_connection(&connection);
name = connection.databaseName;
}
G_debug(3, "name = '%s'", name);
/* parse variables in db.name if present */
if (strchr(name, '$')) {
char **tokens;
int no_tokens, n;
tokens = G_tokenize(name, "/");
no_tokens = G_number_of_tokens(tokens);
name2[0] = '\0';
for (n = 0; n < no_tokens; n++) {
G_chop(tokens[n]);
if (n > 0)
strcat(name2, "/");
G_debug(3, "tokens[%d] = %s", n, tokens[n]);
if (tokens[n][0] == '$') {
G_strchg(tokens[n], '$', ' ');
G_chop(tokens[n]);
strcat(name2, G_getenv_nofatal(tokens[n]));
G_debug(3, " -> %s", G_getenv_nofatal(tokens[n]));
}
else {
strcat(name2, tokens[n]);
}
}
G_free_tokens(tokens);
}
else {
strcpy(name2, name);
}
G_debug(2, "name2 = '%s'", name2);
path = G_store(name2);
path = G_convert_dirseps_to_host(path);
i = strlen(path);
while (path[i] != HOST_DIRSEP && i > 0)
i--;
path[i] = '\0';
if (*path) {
G_debug(2, "path to db is %s", path);
/* create directory if not existing */
if (access(path, 0) != 0) {
if (G_mkdir(path) != 0)
G_fatal_error(
_("Unable to create directory '%s' for sqlite database"),
path);
}
}
G_free(path);
env_nolock = getenv("GRASS_SQLITE_NOLOCK");
if (env_nolock && *env_nolock && atoi(env_nolock)) {
if (sqlite3_config(SQLITE_CONFIG_URI, 1) == SQLITE_OK) {
if (sprintf(name3, "file:%s?nolock=1", name2) < 0) {
return DB_FAILED;
}
G_important_message(_("Disabling SQLite locking"));
}
else {
G_warning(_("The sqlite config option '%s' is not supported"),
"SQLITE_CONFIG_URI");
strcpy(name3, name2);
}
}
else
strcpy(name3, name2);
if (sqlite3_open(name3, &sqlite) != SQLITE_OK) {
db_d_append_error("%s %s\n%s", _("Unable to open database:"), name3,
(char *)sqlite3_errmsg(sqlite));
db_d_report_error();
return DB_FAILED;
}
/* enable loading of extensions */
sqlite3_enable_load_extension(sqlite, 1);
/* set the sqlite busy handler */
sqlite3_busy_handler(sqlite, sqlite_busy_callback, NULL);
return DB_OK;
}
/**
* \brief Close SQLite database.
*
* \return always returns DB_OK
*/
int db__driver_close_database(void)
{
G_debug(3, "db_close_database()");
if (sqlite3_close(sqlite) == SQLITE_BUSY)
G_fatal_error(_("SQLite database connection is still busy"));
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;
char name2[GPATH_MAX], *env_nolock;
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;
}
env_nolock = getenv("GRASS_SQLITE_NOLOCK");
if (env_nolock && *env_nolock && atoi(env_nolock)) {
if (sqlite3_config(SQLITE_CONFIG_URI, 1) == SQLITE_OK) {
if (sprintf(name2, "file:%s?nolock=1", name) < 0) {
return DB_FAILED;
}
G_important_message(_("Disabling SQLite locking"));
}
else {
G_warning(_("The sqlite config option '%s' is not supported"),
"SQLITE_CONFIG_URI");
strcpy(name2, name);
}
}
else
strcpy(name2, name);
if (sqlite3_open(name2, &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_OK;
}
/**
* \brief Delete existing SQLite database.
*
* \param handle dbHandle
*
* \return DB_OK on success
* \return DB_FAILED on failure
*/
int db__driver_delete_database(dbHandle *handle)
{
const char *name;
name = db_get_handle_dbname(handle);
if (access(name, F_OK) != 0) {
db_d_append_error(_("Database <%s> not found"), name);
db_d_report_error();
return DB_FAILED;
}
return remove(name) == 0 ? DB_OK : DB_FAILED;
}
|