Skip to content

Commit

Permalink
Add support for more SQLite database open options. (#565)
Browse files Browse the repository at this point in the history
* Add support for in-memory SQLite databases.

* Add support for opening SQLite databases via file URI.
  • Loading branch information
psychonic committed Dec 4, 2016
1 parent 19db7ae commit 70d8143
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 49 deletions.
4 changes: 3 additions & 1 deletion extensions/sqlite/AMBuilder
Expand Up @@ -12,7 +12,9 @@ elif binary.compiler.vendor == 'msvc':


binary.compiler.defines += [ binary.compiler.defines += [
'SQLITE_OMIT_LOAD_EXTENSION', 'SQLITE_OMIT_LOAD_EXTENSION',
'SQLITE_THREADSAFE' 'SQLITE_THREADSAFE',
'SQLITE_USE_URI',
'SQLITE_ALLOW_URI_AUTHORITY',
] ]
if builder.target_platform == 'linux': if builder.target_platform == 'linux':
binary.compiler.postlink += ['-ldl', '-lpthread'] binary.compiler.postlink += ['-ldl', '-lpthread']
Expand Down
106 changes: 58 additions & 48 deletions extensions/sqlite/driver/SqDriver.cpp
Expand Up @@ -33,6 +33,7 @@
#include "extension.h" #include "extension.h"
#include "SqDriver.h" #include "SqDriver.h"
#include "SqDatabase.h" #include "SqDatabase.h"
#include <am-string.h>


SqDriver g_SqDriver; SqDriver g_SqDriver;


Expand Down Expand Up @@ -178,71 +179,80 @@ inline bool IsPathSepChar(char c)
IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength) IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *error, size_t maxlength)
{ {
ke::AutoLock lock(&m_OpenLock); ke::AutoLock lock(&m_OpenLock);

/* Full path to the database file */
char fullpath[PLATFORM_MAX_PATH];


/* Format our path */ if (strcmp(info->database, ":memory:") == 0 || strncmp(info->database, "file:", 5) == 0)
char path[PLATFORM_MAX_PATH];
size_t len = libsys->PathFormat(path, sizeof(path), "sqlite/%s", info->database);

/* Chop any filename off */
for (size_t i = len-1;
i <= len-1;
i--)
{ {
if (IsPathSepChar(path[i])) ke::SafeStrcpy(fullpath, sizeof(fullpath), info->database);
}
else
{
/* Format our path */
char path[PLATFORM_MAX_PATH];
size_t len = libsys->PathFormat(path, sizeof(path), "sqlite/%s", info->database);

/* Chop any filename off */
for (size_t i = len-1;
i <= len-1;
i--)
{ {
path[i] = '\0'; if (IsPathSepChar(path[i]))
break; {
path[i] = '\0';
break;
}
} }
}


/* Test the full path */ /* Test the full path */
char fullpath[PLATFORM_MAX_PATH]; g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data/%s", path);
g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data/%s", path);
if (!libsys->IsPathDirectory(fullpath))
{
/* Make sure the data folder exists */
len = g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data");
if (!libsys->IsPathDirectory(fullpath)) if (!libsys->IsPathDirectory(fullpath))
{ {
if (!libsys->CreateFolder(fullpath)) /* Make sure the data folder exists */
len = g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data");
if (!libsys->IsPathDirectory(fullpath))
{ {
strncopy(error, "Could not create or open \"data\" folder\"", maxlength); if (!libsys->CreateFolder(fullpath))
return NULL; {
strncopy(error, "Could not create or open \"data\" folder\"", maxlength);
return NULL;
}
} }
}


/* The data folder exists - create each subdir as needed! */ /* The data folder exists - create each subdir as needed! */
char *cur_ptr = path; char *cur_ptr = path;


do do
{
/* Find the next suitable path */
char *next_ptr = cur_ptr;
while (*next_ptr != '\0')
{ {
if (IsPathSepChar(*next_ptr)) /* Find the next suitable path */
char *next_ptr = cur_ptr;
while (*next_ptr != '\0')
{ {
*next_ptr = '\0'; if (IsPathSepChar(*next_ptr))
{
*next_ptr = '\0';
next_ptr++;
break;
}
next_ptr++; next_ptr++;
}
if (*next_ptr == '\0')
{
next_ptr = NULL;
}
len += libsys->PathFormat(&fullpath[len], sizeof(fullpath)-len, "/%s", cur_ptr);
if (!libsys->IsPathDirectory(fullpath) && !libsys->CreateFolder(fullpath))
{
break; break;
} }
next_ptr++; cur_ptr = next_ptr;
} } while (cur_ptr);
if (*next_ptr == '\0') }
{
next_ptr = NULL;
}
len += libsys->PathFormat(&fullpath[len], sizeof(fullpath)-len, "/%s", cur_ptr);
if (!libsys->IsPathDirectory(fullpath) && !libsys->CreateFolder(fullpath))
{
break;
}
cur_ptr = next_ptr;
} while (cur_ptr);
}


/* Build the FINAL path. */ /* Build the FINAL path. */
g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data/sqlite/%s.sq3", info->database); g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data/sqlite/%s.sq3", info->database);
}


/* If we're requesting a persistent connection, see if something is already open */ /* If we're requesting a persistent connection, see if something is already open */
if (persistent) if (persistent)
Expand Down

0 comments on commit 70d8143

Please sign in to comment.