gambas-source-code/main/lib/db/sqlite.c

209 lines
4.2 KiB
C
Raw Normal View History

/***************************************************************************
sqlite.c
(c) 2000-2013 Benoît Minisini <gambas@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
***************************************************************************/
#define __SQLITE_C
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <libgen.h>
#include "main.h"
/* Internal function to check whether a file is a sqlite database file */
static bool is_sqlite2_database(char *filename)
{
FILE* fp;
bool res;
char magic_text[48];
fp = fopen(filename, "r");
if (!fp)
return FALSE;
res = fread(magic_text, 1, 47, fp) == 47;
fclose(fp);
if (!res)
return FALSE;
magic_text[47] = '\0';
if (strcmp(magic_text, "** This file contains an SQLite 2.1 database **"))
return FALSE;
return TRUE;
}
static bool is_sqlite3_database(char *filename)
{
FILE *fp;
bool res;
char magic_text[16];
fp = fopen(filename, "r");
if (!fp)
return FALSE;
res = fread(magic_text, 1, 15, fp) == 15;
fclose(fp);
if (!res)
return FALSE;
magic_text[15] = '\0';
if (strcmp(magic_text, "SQLite format 3"))
return FALSE;
return TRUE;
}
static bool IsDatabaseFile(char *filename)
{
return is_sqlite3_database(filename) || is_sqlite2_database(filename);
}
static char *FindDatabase(char *name, char *hostName)
{
char *dbhome = NULL;
char *fullpath = NULL;
/* Does Name includes fullpath */
if (strcmp(basename(name), name))
{
if (IsDatabaseFile(name))
fullpath = GB.NewZeroString(name);
return fullpath;
}
/* Hostname contains home area */
fullpath = GB.NewZeroString(hostName);
fullpath = GB.AddChar(fullpath, '/');
fullpath = GB.AddString(fullpath, name, 0);
if (IsDatabaseFile(fullpath))
{
return fullpath;
}
GB.FreeString(&fullpath);
/* Check the GAMBAS_SQLITE_DBHOME setting */
dbhome = getenv("GAMBAS_SQLITE_DBHOME");
if (dbhome != NULL)
{
fullpath = GB.NewZeroString(dbhome);
fullpath = GB.AddChar(fullpath, '/');
fullpath = GB.AddString(fullpath, name, 0);
if (IsDatabaseFile(fullpath))
{
return fullpath;
}
}
fullpath = GB.NewZeroString(GB.TempDir());
fullpath = GB.AddString(fullpath, "/sqlite/", 0);
fullpath = GB.AddString(fullpath, name, 0);
if (IsDatabaseFile(fullpath))
{
return fullpath;
}
GB.FreeString(&fullpath);
return NULL;
}
/*****************************************************************************
open_database()
*****************************************************************************/
static int open_database(DB_DESC *desc, DB_DATABASE * db)
{
char *db_fullpath = NULL;
bool ver2 = FALSE;
if (!desc->name) // memory database
goto __SQLITE;
db_fullpath = FindDatabase(desc->name, desc->host);
if (!db_fullpath)
{
[DEVELOPMENT ENVIRONMENT] * NEW: Work continues on integrating the database manager. * NEW: Some cosmetic changes in the way controls are drawing on the form editor. * NEW: Panels with Border property set to None are now drawn with a light border. * BUG: Fix the "Show tab" button and menu. [INTERPRETER] * NEW: _attach is a new dynamic special method that is called when an object is attached to or detached from its event observer. The first argument of this method is the event observer, and the second argument the event handler prefix. [COMPILER] * NEW: An expression can be a NEW instruction now. Beware that it does not work inside braces. [GB.DB] * BUG: Fix an error message in the sqlite handler. [GB.DB.FORM] * NEW: DataSource.Table can now be any SQL query. The Filter property is ignored in that case. * BUG: Setting DataSource.Table to NULL correctly resets the DataSource and its children. * NEW: DataView automatically adjusts the height of its rows to the contents. * NEW: DataSource.CacheSize is a new property to set the number of rows stored in the internal DataSource cache. When this property is set to zero, the cache size takes its default value (64 rows). [GB.DB.SQLITE2] * BUG: Fix a crash in datatype mapping. [GB.DB.SQLITE3] * BUG: Fix a crash in datatype mapping. [GB.QT4] * BUG: Window.AutoResize property works as expected now. * OPT: Some optimizations in GridView. * NEW: GridView.Rows[].Visible returns if a specific row is visible. * NEW: GridView.Rows[].EnsureVisible ensures that a specific row is visible. * BUG: Draw.Style.Panel draws the same thing as a panel border now. * BUG: Window.Closed always returns the accurate value now. git-svn-id: svn://localhost/gambas/trunk@2108 867c0c6c-44f3-4631-809d-bfa615b0a4ec
2009-07-12 23:49:13 +02:00
GB.Error("Unable to locate database: &1", desc->name);
return TRUE;
}
ver2 = is_sqlite2_database(db_fullpath);
GB.FreeString(&db_fullpath);
if (ver2)
goto __SQLITE2;
else
goto __SQLITE3;
__SQLITE:
GB.Component.Load("gb.db.sqlite3");
GB.Error(NULL);
if (GB.Component.Exist("gb.db.sqlite3"))
goto __SQLITE3;
else
goto __SQLITE2;
__SQLITE2:
DB_TryAnother("sqlite2");
return TRUE;
__SQLITE3:
DB_TryAnother("sqlite3");
return TRUE;
}
/*****************************************************************************
The driver interface
*****************************************************************************/
DB_DRIVER DB_sqlite_pseudo_driver =
{
"sqlite",
open_database,
0
};