Add support for more SQLite database open options. (#565)
* Add support for in-memory SQLite databases. * Add support for opening SQLite databases via file URI.
This commit is contained in:
parent
19db7aef46
commit
70d81430f8
@ -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']
|
||||||
|
@ -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;
|
||||||
|
|
||||||
@ -179,70 +180,79 @@ IDatabase *SqDriver::Connect(const DatabaseInfo *info, bool persistent, char *er
|
|||||||
{
|
{
|
||||||
ke::AutoLock lock(&m_OpenLock);
|
ke::AutoLock lock(&m_OpenLock);
|
||||||
|
|
||||||
/* Format our path */
|
/* Full path to the database file */
|
||||||
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]))
|
|
||||||
{
|
|
||||||
path[i] = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Test the full path */
|
|
||||||
char fullpath[PLATFORM_MAX_PATH];
|
char fullpath[PLATFORM_MAX_PATH];
|
||||||
g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data/%s", path);
|
|
||||||
if (!libsys->IsPathDirectory(fullpath))
|
if (strcmp(info->database, ":memory:") == 0 || strncmp(info->database, "file:", 5) == 0)
|
||||||
{
|
{
|
||||||
/* Make sure the data folder exists */
|
ke::SafeStrcpy(fullpath, sizeof(fullpath), info->database);
|
||||||
len = g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data");
|
}
|
||||||
if (!libsys->IsPathDirectory(fullpath))
|
else
|
||||||
{
|
{
|
||||||
if (!libsys->CreateFolder(fullpath))
|
/* Format our path */
|
||||||
{
|
char path[PLATFORM_MAX_PATH];
|
||||||
strncopy(error, "Could not create or open \"data\" folder\"", maxlength);
|
size_t len = libsys->PathFormat(path, sizeof(path), "sqlite/%s", info->database);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The data folder exists - create each subdir as needed! */
|
/* Chop any filename off */
|
||||||
char *cur_ptr = path;
|
for (size_t i = len-1;
|
||||||
|
i <= len-1;
|
||||||
do
|
i--)
|
||||||
{
|
{
|
||||||
/* Find the next suitable path */
|
if (IsPathSepChar(path[i]))
|
||||||
char *next_ptr = cur_ptr;
|
|
||||||
while (*next_ptr != '\0')
|
|
||||||
{
|
|
||||||
if (IsPathSepChar(*next_ptr))
|
|
||||||
{
|
|
||||||
*next_ptr = '\0';
|
|
||||||
next_ptr++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
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))
|
|
||||||
{
|
{
|
||||||
|
path[i] = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cur_ptr = next_ptr;
|
}
|
||||||
} while (cur_ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build the FINAL path. */
|
/* Test the full path */
|
||||||
g_pSM->BuildPath(Path_SM, fullpath, sizeof(fullpath), "data/sqlite/%s.sq3", info->database);
|
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->CreateFolder(fullpath))
|
||||||
|
{
|
||||||
|
strncopy(error, "Could not create or open \"data\" folder\"", maxlength);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The data folder exists - create each subdir as needed! */
|
||||||
|
char *cur_ptr = path;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Find the next suitable path */
|
||||||
|
char *next_ptr = cur_ptr;
|
||||||
|
while (*next_ptr != '\0')
|
||||||
|
{
|
||||||
|
if (IsPathSepChar(*next_ptr))
|
||||||
|
{
|
||||||
|
*next_ptr = '\0';
|
||||||
|
next_ptr++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
cur_ptr = next_ptr;
|
||||||
|
} while (cur_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build the FINAL path. */
|
||||||
|
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user