[GB.DB.SQLITE3]

* NEW: Rewrite the SQLite 3 driver. Get rid of all that brain-fucking C++ 
  code. Things should consume less memory, and may be a little bit faster.


git-svn-id: svn://localhost/gambas/trunk@7016 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2015-03-29 23:22:11 +00:00
parent 6b5030a2f1
commit 5b5bb093e7
14 changed files with 857 additions and 4498 deletions

View file

@ -12,7 +12,7 @@ GB_COMPONENT_SEARCH(
sqlite3 ">= 3.0",
[GB_FIND(sqlite3.h, /usr/local/lib /usr/local /opt /usr/lib /usr, include sqlite*/include)],
[GB_FIND(libsqlite3.$SHLIBEXT, /usr/local /opt /usr, lib sqlite*/lib)],
[$C_LIB $CXX_LIB -lsqlite3])
[$C_LIB -lsqlite3])
AC_OUTPUT( \
Makefile \

View file

@ -5,9 +5,10 @@ gblib_LTLIBRARIES = gb.db.sqlite3.la
gb_db_sqlite3_la_LIBADD = @SQLITE3_LIB@
gb_db_sqlite3_la_LDFLAGS = -module @LD_FLAGS@ @SQLITE3_LDFLAGS@
gb_db_sqlite3_la_CXXFLAGS = $(AM_CXXFLAGS) -fexceptions
gb_db_sqlite3_la_CFLAGS = $(AM_CFLAGS)
gb_db_sqlite3_la_CPPFLAGS = @SQLITE3_INC@
gb_db_sqlite3_la_SOURCES = \
main.h main.cpp dataset.h dataset.cpp qry_dat.cpp qry_dat.h sqlitedataset.h \
sqlitedataset.cpp stringhelper.h stringhelper.cpp
main.h main.c \
helper.h helper.c \
gb_buffer.h gb_buffer.c

View file

@ -1,706 +0,0 @@
/***************************************************************************
dataset.cpp
(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.
***************************************************************************/
/**********************************************************************
* Copyright (c) 2002, Leo Seib, Hannover
*
* Project: C++ Dynamic Library
* Module: Dataset abstraction later realisation file
* Author: Leo Seib E-Mail: lev@almaty.pointstrike.net
* Begin: 5/04/2002
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**********************************************************************/
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include <time.h>
#include <iostream>
#include <string.h>
#include "dataset.h"
extern "C"
{
//************* Database implementation ***************
Database::Database()
{
active = false; // No connection yet
error = ""; //S_NO_CONNECTION;
host = "";
port = "";
db = "";
login = "";
passwd = "";
sequence_table = "db_sequence";
}
Database::~Database()
{
disconnect(); // Disconnect if connected to database
}
int Database::connectFull(const char *newHost, const char *newPort,
const char *newDb, const char *newLogin,
const char *newPasswd)
{
host = newHost;
port = newPort;
db = newDb;
login = newLogin;
passwd = newPasswd;
return connect();
}
}
//************* Dataset implementation ***************
Dataset::Dataset()
{
db = NULL;
haveError = active = false;
frecno = 0;
fbof = feof = true;
autocommit = true;
select_sql = "";
fields_object = new Fields();
edit_object = new Fields();
}
Dataset::Dataset(Database * newDb)
{
db = newDb;
haveError = active = false;
frecno = 0;
fbof = feof = true;
autocommit = true;
select_sql = "";
fields_object = new Fields();
edit_object = new Fields();
}
Dataset::~Dataset()
{
update_sql.clear();
insert_sql.clear();
delete_sql.clear();
delete fields_object;
delete edit_object;
}
void Dataset::setSqlParams(const char *sqlFrmt, sqlType t, ...)
{
va_list ap;
char sqlCmd[DB_BUFF_MAX + 1];
va_start(ap, t);
vsnprintf(sqlCmd, DB_BUFF_MAX - 1, sqlFrmt, ap);
va_end(ap);
switch (t)
{
case sqlSelect:
set_select_sql(sqlCmd);
break;
case sqlUpdate:
add_update_sql(sqlCmd);
break;
case sqlInsert:
add_insert_sql(sqlCmd);
break;
case sqlDelete:
add_delete_sql(sqlCmd);
break;
case sqlExec:
sql = sqlCmd;
break;
}
}
void Dataset::set_select_sql(const char *sel_sql)
{
select_sql = sel_sql;
}
void Dataset::set_select_sql(const string & sel_sql)
{
select_sql = sel_sql;
}
void Dataset::parse_sql(string & sql)
{
string fpattern, by_what;
pars.set_str(sql.c_str());
for (uint i = 0; i < fields_object->size(); i++)
{
fpattern = ":OLD_" + (*fields_object)[i].props.name;
by_what = "'" + (*fields_object)[i].val.get_asString() + "'";
//cout << "parsing " << fpattern <<by_what<<"\n\n";
sql = pars.replace(fpattern, by_what);
}
for (uint i = 0; i < edit_object->size(); i++)
{
fpattern = ":NEW_" + (*edit_object)[i].props.name;
by_what = "'" + (*edit_object)[i].val.get_asString() + "'";
sql = pars.replace(fpattern, by_what);
}
// StringList before_array, after_array;
// int tag = 0;
// bool eol_reached = false,
// was_changed = false,
// flag = false;
// ExtString which_before, which_after;
// ExtString bef, aft, prev_before, right_side, which_field, changed_field, f_value;
// before_array.add(":NEW_", tag);
// before_array.add(":OLD_", tag);
// after_array.add(")", tag);
// after_array.add(",", tag);
// after_array.add(" ", tag);
// sq.squish();
// bef = sq.before_arr(before_array, which_before);
// while (!(bef == prev_before)) {
// right_side = sq.after(which_before, flag);
// right_side.squish();
// aft = right_side.after_arr(after_array, which_after);
// aft.squish();
// which_field = right_side.before(which_after);
// // checking whather we reach end of line
// if ((which_field == "\0") && (which_before != "\0")) {
// which_field = right_side;
// eol_reached = true;
// }
// // If new field and is in insert or edit mode - looks in edit_object
// if ((which_before == ":NEW_") && (which_field != "\0")) {
// which_field.squish();
// f_value.assign(fv(which_field.getChars()));
// f_value.addslashes();
// changed_field.assign("'");
// changed_field + f_value + "'";
// }
// else
// // else looking old value in the current result set
// if ((which_before == ":OLD_") && (which_field != "\0")) {
// which_field.squish();
// f_value.assign(f_old(which_field.getChars()));
// f_value.addslashes();
// changed_field.assign("'");
// changed_field + f_value + "'";
// }
// if (!eol_reached) {
// sq.assign(bef + changed_field + which_after + aft);
// }
// else {
// if (!was_changed && (which_field != "\0")) {
// sq.assign(bef + changed_field + which_after + aft);
// was_changed = true;
// }
// }
// prev_before = bef;
// bef = sq.before_arr(before_array, which_before);
// }
}
void Dataset::close(void)
{
haveError = false;
frecno = 0;
fbof = feof = true;
active = false;
}
//bool Dataset::seek(int pos=0) {
bool Dataset::seek(int pos)
{
frecno = (pos < num_rows() - 1) ? pos : num_rows() - 1;
frecno = (frecno < 0) ? 0 : frecno;
fbof = feof = (num_rows() == 0) ? true : false;
return frecno;
}
void Dataset::refresh()
{
int row = frecno;
if ((row != 0) && active)
{
close();
open();
seek(row);
}
else
open();
}
void Dataset::first()
{
if (ds_state == dsSelect)
{
frecno = 0;
feof = fbof = (num_rows() > 0) ? false : true;
}
}
void Dataset::next()
{
if (ds_state == dsSelect)
{
fbof = false;
if (frecno < num_rows() - 1)
{
frecno++;
feof = false;
}
else
feof = true;
if (num_rows() <= 0)
fbof = feof = true;
}
}
void Dataset::prev()
{
if (ds_state == dsSelect)
{
feof = false;
if (frecno)
{
frecno--;
fbof = false;
}
else
fbof = true;
if (num_rows() <= 0)
fbof = feof = true;
}
}
void Dataset::last()
{
if (ds_state == dsSelect)
{
frecno = (num_rows() > 0) ? num_rows() - 1 : 0;
feof = fbof = (num_rows() > 0) ? false : true;
}
}
//bool Dataset::goto_rec(int pos=1) {
bool Dataset::goto_rec(int pos)
{
if (ds_state == dsSelect)
{
return seek(pos - 1);
}
return false;
}
#if 0
void Dataset::insert()
{
//cout << "insert\n\n";
for (int i = 0; i < field_count(); i++)
{
(*fields_object)[i].val = "";
(*edit_object)[i].val = "";
//cout <<"Insert:"<<i<<"\n\n";
}
ds_state = dsInsert;
}
#endif
void Dataset::edit()
{
if (ds_state != dsSelect)
{
cerr << "Editing is possible only when query exists!";
return;
}
for (uint i = 0; i < fields_object->size(); i++)
{
(*edit_object)[i].val = (*fields_object)[i].val;
}
ds_state = dsEdit;
}
void Dataset::post()
{
if (ds_state == dsInsert)
make_insert();
else if (ds_state == dsEdit)
make_edit();
}
void Dataset::deletion()
{
if (ds_state == dsSelect)
make_deletion();
}
bool Dataset::set_field_value(const char *f_name, const field_value & value)
{
bool found = false;
if ((ds_state == dsInsert) || (ds_state == dsEdit))
{
for (uint i = 0; i < fields_object->size(); i++)
if ((*edit_object)[i].props.name == f_name)
{
(*edit_object)[i].val = value;
found = true;
}
if (!found)
{
GB.Error("Field not found: &1", f_name);
}
return found;
}
GB.Error("Not in Insert or Edit state");
return found;
}
const field_value & Dataset::get_field_value(const char *f_name)
{
static field_value fv;
if (ds_state != dsInactive)
{
if (ds_state == dsEdit || ds_state == dsInsert)
{
for (uint i = 0; i < edit_object->size(); i++)
if ((*edit_object)[i].props.name == f_name)
return (*edit_object)[i].val;
}
else
{
for (uint i = 0; i < fields_object->size(); i++)
if ((*fields_object)[i].props.name == f_name)
return (*fields_object)[i].val;
}
GB.Error("Field not found: &1", f_name);
}
else
GB.Error("Dataset state is Inactive");
return fv;
}
const field_value & Dataset::get_field_value(int index) //const char *f_name)
{
static field_value fv;
if (ds_state != dsInactive)
{
if (ds_state == dsEdit || ds_state == dsInsert)
return (*edit_object)[index].val;
else
return (*fields_object)[index].val;
}
GB.Error("Dataset state is Inactive");
return fv;
}
const field_value Dataset::f_old(const char *f_name)
{
if (ds_state != dsInactive)
for (uint i = 0; i < fields_object->size(); i++)
if ((*fields_object)[i].props.name == f_name)
return (*fields_object)[i].val;
field_value fv;
return fv;
}
void Dataset::setParamList(const ParamList & params)
{
plist = params;
}
bool Dataset::locate()
{
bool result;
if (plist.empty())
return false;
std::map < string, field_value >::const_iterator i;
first();
while (!eof())
{
result = true;
for (i = plist.begin(); i != plist.end(); ++i)
if (fv(i->first.c_str()).get_asString() == i->second.get_asString())
{
continue;
}
else
{
result = false;
break;
}
if (result)
{
return result;
}
next();
}
return false;
}
bool Dataset::locate(const ParamList & params)
{
plist = params;
return locate();
}
bool Dataset::findNext(void)
{
bool result;
if (plist.empty())
return false;
std::map < string, field_value >::const_iterator i;
while (!eof())
{
result = true;
for (i = plist.begin(); i != plist.end(); ++i)
if (fv(i->first.c_str()).get_asString() == i->second.get_asString())
{
continue;
}
else
{
result = false;
break;
}
if (result)
{
return result;
}
next();
}
return false;
}
void Dataset::add_update_sql(const char *upd_sql)
{
string s = upd_sql;
update_sql.push_back(s);
}
void Dataset::add_update_sql(const string & upd_sql)
{
update_sql.push_back(upd_sql);
}
void Dataset::add_insert_sql(const char *ins_sql)
{
string s = ins_sql;
insert_sql.push_back(s);
}
void Dataset::add_insert_sql(const string & ins_sql)
{
insert_sql.push_back(ins_sql);
}
void Dataset::add_delete_sql(const char *del_sql)
{
string s = del_sql;
delete_sql.push_back(s);
}
void Dataset::add_delete_sql(const string & del_sql)
{
delete_sql.push_back(del_sql);
}
void Dataset::clear_update_sql()
{
update_sql.clear();
}
void Dataset::clear_insert_sql()
{
insert_sql.clear();
}
void Dataset::clear_delete_sql()
{
delete_sql.clear();
}
int Dataset::field_count()
{
return fields_object->size();
}
int Dataset::fieldCount()
{
return fields_object->size();
}
const char *Dataset::fieldName(int n)
{
if (n < field_count() && n >= 0)
return (*fields_object)[n].props.name.c_str();
else
return NULL;
}
int Dataset::fieldSize(int n)
{
if (n < field_count() && n >= 0)
return (*fields_object)[n].props.field_len;
else
return 0;
}
int Dataset::fieldIndex(const char *fn)
{
int index, length;
if (strchr(fn, (int) '.'))
{
/* table name has been supplied */
for (uint i = 0; i < fields_object->size(); i++)
{
//if ((*fields_object)[i].props.name == fn)
if (strcmp((*fields_object)[i].props.name.c_str(), fn) == 0)
return i;
}
}
else
{
for (uint i = 0; i < fields_object->size(); i++)
{
index = (*fields_object)[i].props.name.find('.') + 1;
length = (*fields_object)[i].props.name.length();
/*printf("Field name [%s] find [%s] fn [%s]\n",
(*fields_object)[i].props.name.c_str(),
(*fields_object)[i].props.name.substr(index, length).c_str(), fn); */
//if ((*fields_object)[i].props.name.substr(index, length) == fn){
if (strcmp
((*fields_object)[i].props.name.substr(index, length).c_str(),
fn) == 0)
{
return i;
}
}
}
return -1;
}
int Dataset::fieldType(int n)
{
if (n < field_count() && n >= 0)
{
//cout << (*fields_object)[n].val.gft();
return (*fields_object)[n].val.get_fType();
//return (*fields_object)[n].props.type;
}
else
return 0;
}

View file

@ -1,569 +0,0 @@
/***************************************************************************
dataset.h
(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.
***************************************************************************/
/**********************************************************************
* Copyright (c) 2002, Leo Seib, Hannover
*
* Project:Dataset C++ Dynamic Library
* Module: Dataset abstraction layer header file
* Author: Leo Seib E-Mail: lev@almaty.pointstrike.net
* Begin: 5/04/2002
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**********************************************************************/
#ifndef _DATASET_H
#define _DATASET_H
#include <cstdio>
#include <string>
#include "stringhelper.h"
#include <map>
#include <list>
#include "qry_dat.h"
extern "C"
{
#include "gambas.h"
#include "gb_common.h"
#include "../gb.db.h"
extern GB_INTERFACE GB;
class Dataset; // forward declaration of class Dataset
#define S_NO_CONNECTION "No active connection";
#define DB_BUFF_MAX 8*1024 // Maximum buffer's capacity
#define DB_CONNECTION_NONE 0
#define DB_CONNECTION_OK 1
#define DB_CONNECTION_BAD 2
#define DB_COMMAND_OK 0 // OK - command executed
#define DB_EMPTY_QUERY 1 // Query didn't return tuples
#define DB_TUPLES_OK 2 // Query returned tuples
#define DB_ERROR 5
#define DB_BAD_RESPONSE 6
#define DB_UNEXPECTED 7 // This shouldn't ever happen
#define DB_UNEXPECTED_RESULT -1 //For integer functions
/******************* Class Database definition ********************
represents connection with database server;
******************************************************************/
class Database
{
protected:
bool active;
string error, // Error description
host, port, db, login, passwd, //Login info
sequence_table; //Sequence table for nextid
public:
/* constructor */
Database();
/* destructor */
virtual ~Database();
virtual Dataset *CreateDataset() const = 0;
/* sets a new host name */
void setHostName(const char *newHost)
{
host = newHost;
}
/* gets a host name */
const char *getHostName(void) const
{
return host.c_str();
}
/* sets a new port */
void setPort(const char *newPort)
{
port = newPort;
}
/* gets a port */
const char *getPort(void) const
{
return port.c_str();
}
/* sets a new database name */
void setDatabase(const char *newDb)
{
db = newDb;
}
/* gets a database name */
const char *getDatabase(void) const
{
return db.c_str();
}
/* sets a new login to database */
void setLogin(const char *newLogin)
{
login = newLogin;
}
/* gets a login */
const char *getLogin(void) const
{
return login.c_str();
}
/* sets a password */
void setPasswd(const char *newPasswd)
{
passwd = newPasswd;
}
/* gets a password */
const char *getPasswd(void) const
{
return passwd.c_str();
}
/* active status is OK state */
virtual bool isActive(void) const
{
return active;
}
/* Set new name of sequence table */
void setSequenceTable(const char *new_seq_table)
{
sequence_table = new_seq_table;
};
/* Get name of sequence table */
const char *getSequenceTable(void)
{
return sequence_table.c_str();
}
/* virtual methods that must be overloaded in derived classes */
virtual int init(void)
{
return DB_COMMAND_OK;
}
virtual int status(void)
{
return DB_CONNECTION_NONE;
}
virtual int setErr(int err_code) = 0;
virtual const char *getErrorMsg(void)
{
return error.c_str();
}
virtual int connect(void)
{
return DB_COMMAND_OK;
}
virtual int connectFull(const char *newDb, const char *newHost = NULL,
const char *newLogin =
NULL, const char *newPasswd =
NULL, const char *newPort = NULL);
virtual void disconnect(void)
{
active = false;
}
virtual int reset(void)
{
return DB_COMMAND_OK;
}
virtual int create(void)
{
return DB_COMMAND_OK;
}
virtual int drop(void)
{
return DB_COMMAND_OK;
}
virtual long nextid(const char *seq_name) = 0;
/* virtual methods for transaction */
virtual void start_transaction()
{
};
virtual void commit_transaction()
{
};
virtual void rollback_transaction()
{
};
virtual bool in_transaction()
{
return false;
};
};
}
/******************* Class Dataset definition *********************
global abstraction for using Databases
******************************************************************/
// define Dataset States type
enum dsStates
{ dsSelect, dsInsert, dsEdit, dsUpdate, dsDelete, dsInactive };
enum sqlType
{ sqlSelect, sqlUpdate, sqlInsert, sqlDelete, sqlExec };
typedef std::list < string > StringList;
typedef std::map < string, field_value > ParamList;
class Dataset
{
protected:
/* char *Host = ""; //WORK_HOST;
char *Database = ""; //WORK_DATABASE;
char *User = ""; //WORK_USER;
char *Password = ""; //WORK_PASSWORD;
*/
Database * db; // info about db connection
dsStates ds_state; // current state
Fields *fields_object, *edit_object;
bool active; // Is Query Opened?
bool haveError;
int frecno; // number of current row bei bewegung
string sql;
str_helper pars;
ParamList plist; // Paramlist for locate
bool fbof, feof;
bool autocommit; // for transactions
/* Variables to store SQL statements */
string empty_sql; // Executed when result set is empty
string select_sql; // May be only single string variable
StringList update_sql; // May be an array in complex queries
/* Field values for updating must has prefix :NEW_ and :OLD_ and field name
Example:
update wt_story set idobject set idobject=:NEW_idobject,body=:NEW_body
where idobject=:OLD_idobject
Essentually fields idobject and body must present in the
result set (select_sql statement) */
StringList insert_sql; // May be an array in complex queries
/* Field values for inserting must has prefix :NEW_ and field name
Example:
insert into wt_story (idobject, body) values (:NEW_idobject, :NEW_body)
Essentually fields idobject and body must present in the
result set (select_sql statement) */
StringList delete_sql; // May be an array in complex queries
/* Field values for deleing must has prefix :OLD_ and field name
Example:
delete from wt_story where idobject=:OLD_idobject
Essentually field idobject must present in the
result set (select_sql statement) */
/* Arrays for searching */
// StringList names, values;
/* Makes direct inserts into database via mysql_query function */
virtual void make_insert() = 0;
/* Edit SQL */
virtual void make_edit() = 0;
/* Delete SQL */
virtual void make_deletion() = 0;
/* This function works only with MySQL database
Filling the fields information from select statement */
virtual void fill_fields(void) = 0;
/* Parse Sql - replacing fields with prefixes :OLD_ and :NEW_ with current values of OLD or NEW field. */
void parse_sql(string & sql);
/* Returns old field value (for :OLD) */
virtual const field_value f_old(const char *f);
public:
/* constructor */
Dataset();
Dataset(Database * newDb);
/* destructor */
virtual ~Dataset();
/* sets a new value of connection to database */
void setDatabase(Database * newDb)
{
db = newDb;
}
/* retrieves a database which connected */
Database *getDatabase(void)
{
return db;
}
/* sets a new query string to database server */
void setExecSql(const char *newSql)
{
sql = newSql;
}
/* retrieves a query string */
const char *getExecSql(void)
{
return sql.c_str();
}
/* status active is OK query */
virtual bool isActive(void)
{
return active;
}
virtual void setSqlParams(const char *sqlFrmt, sqlType t, ...);
/* error handling */
// virtual void halt(const char *msg);
/* sequence numbers */
virtual long nextid(const char *seq_name) = 0;
/* sequence numbers */
virtual int num_rows() = 0;
/* Open SQL query */
virtual void open(const string & sql) = 0;
virtual void open() = 0;
/* as open, but with our query exept Sql */
virtual bool query(const char *sql) = 0;
/* Close SQL Query*/
virtual void close();
virtual result_set *getResult() = 0;
/* This function looks for field Field_name with value equal Field_value
Returns true if found (position of dataset is set to founded position)
and false another way (position is not changed). */
// virtual bool lookup(char *field_name, char*field_value);
/* Refresh dataset (reopen it and set the same cursor position) */
virtual void refresh();
/* Go to record No (starting with 0) */
virtual bool seek(int pos = 0);
/* Go to record No (starting with 1) */
virtual bool goto_rec(int pos = 1);
/* Go to the first record in dataset */
virtual void first();
/* Go to next record in dataset */
virtual void next();
/* Go to porevious record */
virtual void prev();
/* Go to last record in dataset */
virtual void last();
/* Check for Ending dataset */
virtual bool eof(void)
{
return feof;
}
/* Check for Begining dataset */
virtual bool bof(void)
{
return fbof;
}
/* Start the insert mode */
//virtual void insert();
/* Start the insert mode (alias for insert() function) */
//virtual void append()
//{
// insert();
//}
/* Start the edit mode */
virtual void edit();
/* Add changes, that were made during insert or edit states of dataset into the database */
virtual void post();
/* Delete statements from database */
virtual void deletion();
/* Cancel changes, made in insert or edit states of dataset */
virtual void cancel()
{
};
virtual void setParamList(const ParamList & params);
virtual bool locate();
virtual bool locate(const ParamList & params);
virtual bool findNext();
/* func. retrieves a number of fields */
/* Number of fields in a record */
virtual int field_count();
virtual int fieldCount();
/* func. retrieves a field name with 'n' index */
virtual const char *fieldName(int n);
/* func. retrieves a field index with 'fn' field name,return -1 when field name not found */
virtual int fieldIndex(const char *fn);
/* func. retrieves a field size */
virtual int fieldSize(int n);
/* func. retrieves a field type of field index NG 30/08/03*/
virtual int fieldType(int n);
/* Set field value */
virtual bool set_field_value(const char *f_name, const field_value & value);
/* alias for set_field_value */
virtual bool sf(const char *f, const field_value & v)
{
return set_field_value(f, v);
}
/* Return field name by it index */
// virtual char *field_name(int f_index) { return field_by_index(f_index)->get_field_name(); };
/* Getting value of field for current record */
virtual const field_value & get_field_value(const char *f_name);
/* Alias to get_field_value */
const field_value & fv(const char *name)
{
return get_field_value(name);
}
/* Getting value of field for current record */
virtual const field_value & get_field_value(int index); //const char *f_name);
/* Alias to get_field_value */
const field_value & fv(int index)
{
return get_field_value(index);
}
/* ------------ for transaction ------------------- */
void set_autocommit(bool v)
{
autocommit = v;
}
bool get_autocommit()
{
return autocommit;
}
/* ----------------- for debug -------------------- */
Fields *get_fields_object()
{
return fields_object;
};
Fields *get_edit_object()
{
return edit_object;
};
private:
void set_ds_state(dsStates new_state)
{
ds_state = new_state;
};
public:
/* return ds_state value */
dsStates get_state()
{
return ds_state;
};
/*add a new value to select_sql*/
void set_select_sql(const char *sel_sql);
void set_select_sql(const string & select_sql);
/*add a new value to update_sql*/
void add_update_sql(const char *upd_sql);
void add_update_sql(const string & upd_sql);
/*add a new value to insert_sql*/
void add_insert_sql(const char *ins_sql);
void add_insert_sql(const string & ins_sql);
/*add a new value to delete_sql */
void add_delete_sql(const char *del_sql);
void add_delete_sql(const string & del_sql);
/*clear update_sql*/
void clear_update_sql();
/*clear insert_sql*/
void clear_insert_sql();
/*clear delete_sql*/
void clear_delete_sql();
/*get value of select_sql*/
const char *get_select_sql();
};
#endif

492
gb.db.sqlite3/src/helper.c Normal file
View file

@ -0,0 +1,492 @@
/***************************************************************************
helper.c
(c) 2000-2015 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 __HELPER_C
#include "helper.h"
#include "gb_buffer.h"
//--------------------------------------------------------------------------
static int _last_error = SQLITE_OK;
SQLITE_DATABASE *sqlite_open_database(const char *path, const char *host)
{
SQLITE_DATABASE *db;
sqlite3 *handle;
if (!path)
path = ":memory:";
_last_error = sqlite3_open(path, &handle);
if (_last_error == SQLITE_OK)
{
GB.Alloc(POINTER(&db), sizeof(SQLITE_DATABASE));
db->handle = handle;
db->path = GB.NewZeroString(path);
db->host = GB.NewZeroString(host);
db->error = SQLITE_OK;
return db;
}
else
return NULL;
}
void sqlite_close_database(SQLITE_DATABASE *db)
{
sqlite3_close(db->handle);
GB.FreeString(&db->path);
GB.FreeString(&db->host);
GB.Free(POINTER(&db));
}
const char *sqlite_get_error_message(SQLITE_DATABASE *db)
{
const char *error;
int err;
err = db ? db->error : _last_error;
switch (err)
{
case SQLITE_OK:
error = "Successful result";
break;
case SQLITE_ERROR:
error = sqlite3_errmsg(db->handle);
break;
case SQLITE_INTERNAL:
error = "Internal logic error - Report this error on the mailing-list at sqlite.org";
break;
case SQLITE_PERM:
error = "Access permission denied";
break;
case SQLITE_ABORT:
error = "Callback routine requested an abort";
break;
case SQLITE_BUSY:
error = "The database file is locked";
break;
case SQLITE_LOCKED:
error = "A table in the database is locked";
break;
case SQLITE_NOMEM:
error = "Out of memory";
break;
case SQLITE_READONLY:
error = "Attempt to write a readonly database";
break;
case SQLITE_INTERRUPT:
error = "Operation terminated by sqlite_interrupt()";
break;
case SQLITE_IOERR:
error = "Some kind of disk I/O error occurred";
break;
case SQLITE_CORRUPT:
error = "The database disk image is malformed";
break;
case SQLITE_NOTFOUND:
error = "(Internal Only) Table or record not found";
break;
case SQLITE_FULL:
error = "Insertion failed because database is full";
break;
case SQLITE_CANTOPEN:
error = "Unable to open the database file";
break;
case SQLITE_PROTOCOL:
error = "Database lock protocol error";
break;
case SQLITE_EMPTY:
error = "(Internal Only) Database table is empty";
break;
case SQLITE_SCHEMA:
error = "The database schema changed";
break;
case SQLITE_TOOBIG:
error = "Too much data for one row of a table";
break;
case SQLITE_CONSTRAINT:
error = "Abort due to constraint violation";
break;
case SQLITE_MISMATCH:
error = "Data type mismatch";
break;
default:
error = "Undefined SQLite error";
}
return error;
}
//--------------------------------------------------------------------------
GB_TYPE sqlite_get_type(const char *type, int *length)
{
int i;
char *upper;
GB_TYPE gtype;
char *left, *right;
if (length)
*length = 0;
upper = GB.NewZeroString(type);
for (i = 0; i < GB.StringLength(upper); i++)
upper[i] = toupper(upper[i]);
type = upper;
if (!type || !*type)
{
gtype = GB_T_STRING;
}
else if (strstr(type, "CHAR(") /* note the opening bracket */
|| strstr(type, "CLOB") || strstr(type, "TEXT") /* also catches TINYTEXT */
|| strstr(type, "VARCHAR") || strstr(type, "VARYING CHAR")
|| strstr(type, "ENUM") || strstr(type, "SET") || strstr(type, "YEAR"))
{ /* MySQL 2 or 4 digit year (string) */
gtype = GB_T_STRING;
}
else if (strstr(type, "CHAR") /* this is a 1-byte value */
|| strstr(type, "TINYINT")
|| strstr(type, "INT1") || strstr(type, "BOOL"))
{
gtype = GB_T_BOOLEAN;
}
else if (strstr(type, "SMALLINT") || strstr(type, "INT2"))
{
gtype = GB_T_INTEGER;
}
else if (strstr(type, "MEDIUMINT"))
{
gtype = GB_T_INTEGER;
}
else if (strstr(type, "BIGINT") || strstr(type, "INT8"))
{
gtype = GB_T_LONG;
}
else if (strstr(type, "INTEGER")
|| strstr(type, "INT") || strstr(type, "INT4"))
{
gtype = GB_T_INTEGER;
}
else if (strstr(type, "DECIMAL") || strstr(type, "NUMERIC"))
{
gtype = GB_T_FLOAT;
}
else if (strstr(type, "TIMESTAMP") || strstr(type, "DATETIME"))
{
gtype = GB_T_DATE;
}
else if (strstr(type, "DATE"))
{
gtype = GB_T_DATE;
}
else if (strstr(type, "TIME"))
{
gtype = GB_T_DATE;
}
else if (strstr(type, "DOUBLE") || strstr(type, "FLOAT8"))
{
gtype = GB_T_FLOAT;
}
else if (strstr(type, "REAL") /* this is PostgreSQL "real", not
MySQL "real" which is a
synonym of "double" */
|| strstr(type, "FLOAT")
|| strstr(type, "FLOAT4"))
{
gtype = GB_T_FLOAT;
}
else if (strstr(type, "BLOB")) // BM
{
gtype = DB_T_BLOB;;
}
if (gtype == GB_T_STRING && type && length != NULL)
{
/* if a length has been defined it will be between () */
right = (char *)rindex(type, ')');
left = (char *)index(type, '(');
if (left && right)
{
*right = 0;
*length = atoi(left + 1);
}
}
GB.FreeString(&upper);
return gtype;
}
//--------------------------------------------------------------------------
static int my_sqlite3_exec(
sqlite3 *db, /* The database on which the SQL executes */
const char *zSql, /* The SQL to be executed */
SQLITE_RESULT *result,
bool need_types
)
{
int rc = SQLITE_OK;
const char *zLeftover;
sqlite3_stmt *pStmt = 0;
int ncol;
int nRetry = 0;
int nCallback;
int i;
//fprintf(stderr, "my_sqlite3_exec: %s\n", zSql);
if( zSql==0 ) return SQLITE_OK;
while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] )
{
pStmt = 0;
//fprintf(stderr, "my_sqlite3_exec: sqlite3_prepare_v2 ?\n");
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
if( rc!=SQLITE_OK ){
//fprintf(stderr, "my_sqlite3_exec: sqlite3_prepare_v2 failed: %s\n", sqlite3_errmsg(db));
if( pStmt ) sqlite3_finalize(pStmt);
continue;
}
if( !pStmt ){
/* this happens for a comment or white-space */
zSql = zLeftover;
continue;
}
nCallback = 0;
result->ncol = ncol = sqlite3_column_count(pStmt);
if (ncol > 0)
{
GB.Alloc(POINTER(&result->names), ncol * sizeof(const char *));
if (need_types)
{
GB.Alloc(POINTER(&result->types), ncol * sizeof(int));
GB.Alloc(POINTER(&result->lengths), ncol * sizeof(int));
}
}
GB.NewArray(POINTER(&result->values), sizeof(int), 0);
for(;;)
{
rc = sqlite3_step(pStmt);
/* Invoke the callback function if required */
if((SQLITE_ROW==rc ||
//(SQLITE_DONE==rc && !nCallback && db->flags&SQLITE_NullCallback)) ){
(SQLITE_DONE==rc && !nCallback && 1)) )
{
if (0 == nCallback)
{
for (i = 0; i < ncol; i++)
result->names[i] = GB.NewZeroString(sqlite3_column_name(pStmt, i));
if (need_types)
{
for (i = 0; i < ncol; i++)
result->types[i] = sqlite_get_type(sqlite3_column_decltype(pStmt, i), &result->lengths[i]);
}
nCallback++;
}
if (rc == SQLITE_ROW)
{
int *addr = GB.Insert(&result->values, -1, ncol * 2);
char *value;
int len;
result->nrow++;
for (i = 0; i < ncol; i++)
{
if (sqlite3_column_type(pStmt, i) == SQLITE_BLOB)
value = (char *)sqlite3_column_blob(pStmt, i);
else
value = (char *)sqlite3_column_text(pStmt, i);
len = sqlite3_column_bytes(pStmt, i);
if (len == 0)
addr[i * 2] = BUFFER_length(result->buffer) - 1;
else
{
addr[i * 2] = BUFFER_add(&result->buffer, value, len + 1);
result->buffer[BUFFER_length(result->buffer) - 1] = 0;
}
addr[i * 2 + 1] = len;
}
}
}
if (rc != SQLITE_ROW)
{
rc = sqlite3_finalize(pStmt);
pStmt = 0;
if (rc != SQLITE_SCHEMA)
{
nRetry = 0;
zSql = zLeftover;
while( isspace((unsigned char)zSql[0]) ) zSql++;
}
break;
}
}
}
if (pStmt)
sqlite3_finalize(pStmt);
return rc;
}
SQLITE_RESULT *sqlite_query_exec(SQLITE_DATABASE *db, const char *query, bool need_types)
{
SQLITE_RESULT *result;
int retry;
int res;
GB.AllocZero(POINTER(&result), sizeof(SQLITE_RESULT));
BUFFER_create(&result->buffer);
for (retry = 1; retry <= 2; retry++)
{
res = my_sqlite3_exec(db->handle, query, result, need_types);
if (res != SQLITE_SCHEMA)
break;
}
if (res != SQLITE_OK)
{
db->error = res;
sqlite_query_free(result);
return NULL;
}
else
return result;
}
void sqlite_query_free(SQLITE_RESULT *result)
{
int i;
for (i = 0; i < result->ncol; i++)
GB.FreeString(&result->names[i]);
GB.Free(POINTER(&result->names));
GB.Free(POINTER(&result->types));
GB.Free(POINTER(&result->lengths));
GB.FreeArray(&result->values);
BUFFER_delete(&result->buffer);
GB.Free(POINTER(&result));
}
void sqlite_query_get(SQLITE_RESULT *result, int pos, int col, char **value, int *length)
{
int i;
if (pos < 0 || pos >= result->nrow || col < 0 || col >= result->ncol)
{
*value = NULL;
if (length)
*length = 0;
return;
}
i = pos * result->ncol * 2 + col * 2;
*value = result->buffer + result->values[i];
if (length)
*length = result->values[i + 1];
}
char *sqlite_query_get_string(SQLITE_RESULT *result, int pos, int col)
{
char *value;
sqlite_query_get(result, pos, col, &value, NULL);
return value ? value : "";
}
int sqlite_query_get_int(SQLITE_RESULT *result, int pos, int col)
{
char *value;
sqlite_query_get(result, pos, col, &value, NULL);
if (!value)
return 0;
else
return atoi(value);
}
int sqlite_query_find_field(SQLITE_RESULT *result, const char *name)
{
int i;
char *field;
char *p;
/*fprintf(stderr, "sqlite_query_find_field: %s\n", name);
for (i = 0; i < result->ncol; i++)
fprintf(stderr, "'%s' ", result->names[i]);
fprintf(stderr, "\n");*/
if (strchr(name, '.'))
{
for (i = 0; i < result->ncol; i++)
{
if (strcmp(result->names[i], name) == 0)
return i;
}
}
else
{
for (i = 0; i < result->ncol; i++)
{
field = result->names[i];
p = strchr(field, '.');
if (p)
field = p + 1;
if (strcmp(field, name) == 0)
return i;
}
}
return -1;
}

View file

@ -0,0 +1,68 @@
/***************************************************************************
helper.h
(c) 2000-2015 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.
***************************************************************************/
#ifndef __HELPER_H
#define __HELPER_H
#include "main.h"
#include "gb_buffer.h"
typedef
struct {
sqlite3 *handle;
char *path;
char *host;
int error;
}
SQLITE_DATABASE;
SQLITE_DATABASE *sqlite_open_database(const char *name, const char *host);
void sqlite_close_database(SQLITE_DATABASE *db);
const char *sqlite_get_error_message(SQLITE_DATABASE *db);
typedef
struct {
SQLITE_DATABASE *db;
int nrow;
int ncol;
char **names;
int *types;
int *lengths;
char *buffer;
int *values;
}
SQLITE_RESULT;
GB_TYPE sqlite_get_type(const char *type, int *length);
SQLITE_RESULT *sqlite_query_exec(SQLITE_DATABASE *db, const char *query, bool need_types);
void sqlite_query_free(SQLITE_RESULT *result);
int sqlite_query_find_field(SQLITE_RESULT *result, const char *name);
void sqlite_query_get(SQLITE_RESULT *result, int pos, int col, char **value, int *length);
char *sqlite_query_get_string(SQLITE_RESULT *result, int pos, int col);
int sqlite_query_get_int(SQLITE_RESULT *result, int pos, int col);
#endif /* __HELPER_H */

File diff suppressed because it is too large Load diff

View file

@ -24,24 +24,16 @@
#ifndef __MAIN_H
#define __MAIN_H
extern "C"
{
#include "gambas.h"
#include "gb_common.h"
#include "../gb.db.h"
#include "sqlite3.h"
#ifndef __MAIN_C
extern GB_INTERFACE GB;
extern DB_INTERFACE DB;
#endif
}
#define QUOTE_STRING "\""
#define TRUE 1
#define FALSE 0
/* Prototypes Required to allow cpp compilation */
#include "gb.db.proto.h"
#endif /* __MAIN_H */

View file

@ -1,671 +0,0 @@
/***************************************************************************
qry_dat.cpp
(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.
***************************************************************************/
/**********************************************************************
* Copyright (c) 2002, Leo Seib, Hannover
*
* Project: C++ Dynamic Library
* Module: FieldValue class realisation file
* Author: Leo Seib E-Mail: lev@almaty.pointstrike.net
* Begin: 5/04/2002
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**********************************************************************/
#include "qry_dat.h"
extern "C" {
#include "gambas.h"
extern GB_INTERFACE GB;
}
//Constructors
field_value::field_value()
{
str_value = "";
blob_value = NULL;
len = 0;
field_type = ft_String;
is_null = true;
};
//empty destructor
field_value::~field_value()
{
if (blob_value)
{
//fprintf(stderr, "free %p\n", blob_value);
GB.Free(&blob_value);
}
}
string field_value::get_asString() const
{
//static string tmp;
//tmp = str_value;
return str_value;
};
char *field_value::get_asBlob() const
{
string tmp;
switch (field_type)
{
case ft_Blob:
{
return (char *)blob_value;
}
default:
{
return (char *)get_asString().data();
}
}
};
bool field_value::get_asBool() const
{
return (str_value != "" && str_value != "0");
};
int field_value::get_asInteger() const
{
return atoi(str_value.data());
};
#if 0
char field_value::get_asChar() const
{
switch (field_type)
{
case ft_String:
{
return str_value[0];
}
case ft_Boolean:
{
char c;
if (bool_value)
return c = 'T';
else
return c = 'F';
}
case ft_Char:
{
return char_value;
}
case ft_Short:
{
char t[ft_Short_Length];
sprintf(t, "%i", short_value);
return t[0];
}
case ft_UShort:
{
char t[ft_Short_Length];
sprintf(t, "%i", ushort_value);
return t[0];
}
case ft_Long:
{
char t[ft_Long_Length];
sprintf(t, "%ld", long_value);
return t[0];
}
case ft_ULong:
{
char t[ft_Long_Length];
sprintf(t, "%lu", ulong_value);
return t[0];
}
case ft_Float:
case ft_Double:
{
char t[ft_Double_Length];
sprintf(t, "%f", double_value);
return t[0];
}
default:
{
return str_value[0];
}
}
};
short field_value::get_asShort() const
{
switch (field_type)
{
case ft_String:
{
return (short) atoi(str_value.c_str());
}
case ft_Boolean:
{
return (short) bool_value;
}
case ft_Char:
{
return (short) char_value;
}
case ft_Short:
{
return short_value;
}
case ft_UShort:
{
return (short) ushort_value;
}
case ft_Long:
{
return (short) long_value;
}
case ft_ULong:
{
return (short) ulong_value;
}
case ft_Float:
case ft_Double:
{
return (short) double_value;
}
default:
{
return (short) atoi(str_value.c_str());
}
}
};
unsigned short field_value::get_asUShort() const
{
switch (field_type)
{
case ft_String:
{
return (unsigned short) atoi(str_value.c_str());
}
case ft_Boolean:
{
return (unsigned short) bool_value;
}
case ft_Char:
{
return (unsigned short) char_value;
}
case ft_Short:
{
return (unsigned short) short_value;
}
case ft_UShort:
{
return ushort_value;
}
case ft_Long:
{
return (unsigned short) long_value;
}
case ft_ULong:
{
return (unsigned short) ulong_value;
}
case ft_Float:
case ft_Double:
{
return (unsigned short) double_value;
}
default:
{
return (unsigned short) atoi(str_value.c_str());
}
}
};
long field_value::get_asLong() const
{
switch (field_type)
{
case ft_String:
{
return (long) atoi(str_value.c_str());
}
case ft_Boolean:
{
return (long) bool_value;
}
case ft_Char:
{
return (long) char_value;
}
case ft_Short:
{
return (long) short_value;
}
case ft_UShort:
{
return (long) ushort_value;
}
case ft_Long:
{
return long_value;
}
case ft_ULong:
{
return (long) ulong_value;
}
case ft_Float:
case ft_Double:
{
return (long) double_value;
}
default:
{
return (long) atoi(str_value.c_str());
}
}
};
int field_value::get_asInteger() const
{
return (int) get_asLong();
}
unsigned long field_value::get_asULong() const
{
switch (field_type)
{
case ft_String:
{
return (unsigned long) atoi(str_value.c_str());
}
case ft_Boolean:
{
return (unsigned long) bool_value;
}
case ft_Char:
{
return (unsigned long) char_value;
}
case ft_Short:
{
return (unsigned long) short_value;
}
case ft_UShort:
{
return (unsigned long) ushort_value;
}
case ft_Long:
{
return (unsigned long) long_value;
}
case ft_ULong:
{
return ulong_value;
}
case ft_Float:
case ft_Double:
{
return (unsigned long) double_value;
}
default:
{
return (unsigned long) atoi(str_value.c_str());
}
}
};
double field_value::get_asDouble() const
{
switch (field_type)
{
case ft_String:
{
return atof(str_value.c_str());
}
case ft_Boolean:
{
return (double) bool_value;
}
case ft_Char:
{
return (double) char_value;
}
case ft_Short:
{
return (double) short_value;
}
case ft_UShort:
{
return (double) ushort_value;
}
case ft_Long:
{
return (double) long_value;
}
case ft_ULong:
{
return (double) ulong_value;
}
case ft_Float:
case ft_Double:
{
return (double) double_value;
}
default:
{
return atof(str_value.c_str());
}
}
};
#endif
field_value & field_value::operator=(const field_value & fv)
{
if (this == &fv)
return *this;
if (fv.get_isNull())
{
set_isNull(fv.get_fType());
}
else
{
switch (fv.get_fType())
{
/*
case ft_String:
{
set_asString(fv.get_asString());
break;
}
case ft_Boolean:
{
set_asBool(fv.get_asBool());
break;
}
case ft_Char:
{
set_asChar(fv.get_asChar());
break;
}
case ft_Short:
{
set_asShort(fv.get_asShort());
break;
}
case ft_UShort:
{
set_asUShort(fv.get_asUShort());
break;
}
case ft_Long:
{
set_asLong(fv.get_asLong());
break;
}
case ft_ULong:
{
set_asULong(fv.get_asULong());
break;
}
case ft_Float:
case ft_Double:
{
set_asDouble(fv.get_asDouble());
break;
}
case ft_Date:
{
set_asDate(fv.get_asString());
break;
}*/
case ft_Blob:
{
set_asBlob(fv.get_asBlob(), fv.get_len());
break;
}
default:
{
set_asString(fv.get_asString(), fv.get_field_type());
break;
}
}
}
return *this;
};
//Set functions
void field_value::set_isNull(fType type)
{
is_null = true;
field_type = type;
str_value = "";
if (type == ft_Blob)
set_asBlob(NULL, 0);
}
void field_value::set_asString(const char *s, fType type)
{
str_value = s;
field_type = type;
is_null = s == NULL || *s == 0;
};
void field_value::set_asString(const string & s, fType type)
{
str_value = s;
field_type = type;
is_null = s.length() == 0;
};
#if 0
void field_value::set_asBool(const bool b)
{
bool_value = b;
field_type = ft_Boolean;
is_null = false;
};
void field_value::set_asChar(const char c)
{
char_value = c;
field_type = ft_Char;
is_null = false;
};
void field_value::set_asShort(const short s)
{
short_value = s;
field_type = ft_Short;
is_null = false;
};
void field_value::set_asUShort(const unsigned short us)
{
ushort_value = us;
field_type = ft_UShort;
is_null = false;
};
void field_value::set_asLong(const long l)
{
long_value = l;
field_type = ft_Long;
is_null = false;
};
void field_value::set_asInteger(const int i)
{
long_value = (long) i;
field_type = ft_Long;
is_null = false;
};
void field_value::set_asULong(const unsigned long ul)
{
long_value = ul;
field_type = ft_ULong;
is_null = false;
};
void field_value::set_asDouble(const double d)
{
double_value = d;
field_type = ft_Double;
is_null = false;
};
void field_value::set_asDate(const char *s)
{ //NG
str_value = s;
field_type = ft_Date;
is_null = false;
};
void field_value::set_asDate(const string & s)
{ //NG
str_value = s;
field_type = ft_Date;
is_null = false;
};
#endif
void field_value::set_asBlob(const char *data, int l) // BM
{
//fprintf(stderr, "set_asBlob: (%p %d) [%p %d]\n", blob_value, len, data, l);
if (blob_value)
{
GB.Free(&blob_value);
blob_value = NULL;
}
if (l)
{
GB.Alloc(&blob_value, l);
::memcpy(blob_value, data, l);
}
//fprintf(stderr, " -> %p\n", blob_value);
len = l;
field_type = ft_Blob;
is_null = (l == 0);
};
string field_value::gft()
{
string tmp;
switch (field_type)
{
case ft_String:
{
tmp.assign("string");
return tmp;
}
case ft_Blob:
{
tmp.assign("blob");
return tmp;
}
case ft_Boolean:
{
tmp.assign("bool");
return tmp;
}
case ft_Char:
{
tmp.assign("char");
return tmp;
}
case ft_Short:
{
tmp.assign("short");
return tmp;
}
case ft_Long:
{
tmp.assign("long");
return tmp;
}
case ft_Float:
{
tmp.assign("float");
return tmp;
}
case ft_Double:
{
tmp.assign("double");
return tmp;
}
case ft_Date:
{
tmp.assign("date");
return tmp;
}
default:
break;
}
tmp.assign("string");
return tmp;
}

View file

@ -1,302 +0,0 @@
/***************************************************************************
qry_dat.h
(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.
***************************************************************************/
/**********************************************************************
* Copyright (c) 2002, Leo Seib, Hannover
*
* Project:Dataset C++ Dynamic Library
* Module: FieldValue class and result sets classes header file
* Author: Leo Seib E-Mail: lev@almaty.pointstrike.net
* Begin: 5/04/2002
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**********************************************************************/
using namespace std;
#include <string>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <map>
#include <vector>
#include <iostream>
#include "sqlite3.h"
enum fType
{
ft_String,
ft_Boolean,
ft_Char,
ft_WChar,
ft_WideString,
ft_Short,
ft_UShort,
ft_Long,
ft_ULong,
ft_Float,
ft_Double,
ft_LongDouble,
ft_Date,
ft_Object,
ft_Blob // BM
};
/* Size of Strings for fType */
#define ft_Boolean_Length 5 //TRUE or FALSE
#define ft_Short_Length 10
#define ft_LongDouble_Length 32
#define ft_Long_Length 12
#define ft_Float_Length 16
#define ft_Date_Length 19
#define ft_Double_Length 32
class field_value
{
private:
fType field_type;
string str_value;
void *blob_value;
bool is_null;
int len;
public:
field_value();
~field_value();
int get_len() const { return len; }
fType get_fType() const
{
return field_type;
}
fType get_field_type() const
{
return field_type;
}
string gft();
bool get_isNull() const
{
return is_null;
}
string get_asString() const;
char *get_asBlob() const;
bool get_asBool() const;
int get_asInteger() const;
#if 0
char get_asChar() const;
short get_asShort() const;
unsigned short get_asUShort() const;
long get_asLong() const;
unsigned long get_asULong() const;
double get_asDouble() const;
#endif
#if 0
field_value & operator=(const char *s)
{
set_asString(s);
return *this;
}
field_value & operator=(const string & s)
{
set_asString(s);
return *this;
}
#endif
#if 0
field_value & operator=(const bool b)
{
set_asBool(b);
return *this;
}
field_value & operator=(const short s)
{
set_asShort(s);
return *this;
}
field_value & operator=(const unsigned short us)
{
set_asUShort(us);
return *this;
}
field_value & operator=(const long l)
{
set_asLong(l);
return *this;
}
field_value & operator=(const unsigned long l)
{
set_asULong(l);
return *this;
}
field_value & operator=(const int i)
{
set_asLong(i);
return *this;
}
field_value & operator=(const double d)
{
set_asDouble(d);
return *this;
}
#endif
field_value & operator=(const field_value & fv);
//class ostream;
#if 0
friend ostream & operator<<(ostream & os, const field_value & fv)
{
switch (fv.get_fType())
{
case ft_String:
case ft_Blob:
case ft_WideString:
case ft_WChar:
case ft_Object:
{
return os << fv.get_asString();
break;
}
case ft_Date:
{
return os << fv.get_asString();
break;
}
case ft_Boolean:
{
return os << fv.get_asBool();
break;
}
case ft_Char:
{
return os << fv.get_asChar();
break;
}
case ft_Short:
{
return os << fv.get_asShort();
break;
}
case ft_UShort:
{
return os << fv.get_asUShort();
break;
}
case ft_Long:
{
return os << fv.get_asLong();
break;
}
case ft_ULong:
{
return os << fv.get_asULong();
break;
}
case ft_Float:
case ft_LongDouble:
case ft_Double:
{
return os << fv.get_asDouble();
break;
}
}
}
#endif
void set_isNull(fType f);
void set_asString(const char *s, fType type);
void set_asString(const string & s, fType type);
void set_asBlob(const char *s, int l); //BM
/*void set_asBool(const bool b);
void set_asChar(const char c);
void set_asShort(const short s);
void set_asUShort(const unsigned short us);
void set_asInteger(const int i);
void set_asLong(const long l);
void set_asULong(const unsigned long l);
void set_asDouble(const double d);
void set_asDate(const char *s); //NG
void set_asDate(const string & s); //NG*/
};
struct field_prop
{
string name, display_name;
fType type;
string field_table; //?
bool read_only;
unsigned int field_len;
unsigned int field_flags;
unsigned int notnull;
int idx;
};
struct field
{
field_prop props;
field_value val;
};
typedef map < int, field > Fields;
typedef map < int, field_value > sql_record;
typedef map < int, field_prop > record_prop;
typedef map < int, sql_record > query_data;
typedef field_value variant;
//typedef Fields::iterator fld_itor;
typedef sql_record::iterator rec_itor;
typedef record_prop::iterator recprop_itor;
typedef query_data::iterator qry_itor;
struct result_set
{
sqlite3 *conn; //NG
record_prop record_header;
query_data records;
};

File diff suppressed because it is too large Load diff

View file

@ -1,210 +0,0 @@
/***************************************************************************
sqlitedataset.h
(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.
***************************************************************************/
/**********************************************************************
* Copyright (c) 2002, Leo Seib, Hannover
*
* Project:SQLiteDataset C++ Dynamic Library
* Module: SQLiteDataset class header file
* Author: Leo Seib E-Mail: lev@almaty.pointstrike.net
* Begin: 5/04/2002
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**********************************************************************/
#ifndef _SQLITEDATASET_H
#define _SQLITEDATASET_H
#include <stdio.h>
#include "dataset.h"
#include "sqlite3.h"
extern "C"
{
#include "gambas.h"
#include "gb_common.h"
#include "../gb.db.h"
extern GB_INTERFACE GB;
extern DB_INTERFACE DB;
}
/* NG */
using namespace std;
#include <string>
#include <vector>
typedef vector < string > Tables;
//#define DEFAULT_STRING_LENGTH 65535
#define DEFAULT_STRING_LENGTH 0
/* */
/* Return Field Type from Database */
void SetFieldType(result_set * r, Tables tables);
fType GetFieldType(const char *Type, unsigned int *len);
/***************** Class SqliteDatabase definition ******************
class 'SqliteDatabase' connects with Sqlite-server
******************************************************************/
class SqliteDatabase:public Database
{
protected:
/* connect descriptor */
sqlite3 * conn;
bool _in_transaction;
int last_err;
public:
/* default constructor */
SqliteDatabase();
/* destructor */
virtual ~SqliteDatabase();
Dataset *CreateDataset() const;
/* func. returns connection handle with SQLite-server */
sqlite3 *getHandle()
{
return conn;
}
/* func. returns current status about SQLite-server connection */
virtual int status();
virtual int setErr(int err_code);
/* func. returns error message if error occurs */
virtual const char *getErrorMsg();
/* func. connects to database-server */
virtual int connect();
/* func. disconnects from database-server */
virtual void disconnect();
/* func. creates new database */
virtual int create();
/* func. deletes database */
virtual int drop();
virtual long nextid(const char *seq_name);
/* virtual methods for transaction */
virtual void start_transaction();
virtual void commit_transaction();
virtual void rollback_transaction();
bool in_transaction() { return _in_transaction; }
int lastError() { return last_err; }
};
/***************** Class SqliteDataset definition *******************
class 'SqliteDataset' does a query to SQLite-server
******************************************************************/
class SqliteDataset:public Dataset
{
protected:
/* query results*/
result_set result;
sqlite3 *handle();
/* Makes direct queries to database */
virtual void make_query(StringList & _sql);
/* Makes direct inserts into database */
virtual void make_insert();
/* Edit SQL */
virtual void make_edit();
/* Delete SQL */
virtual void make_deletion();
/* Filling the fields information from select statement */
virtual void fill_fields();
/* Changing field values during dataset navigation */
public:
/* constructor */
SqliteDataset();
SqliteDataset(SqliteDatabase * newDb);
/* destructor */
virtual ~SqliteDataset();
/* opens a query & then sets a query results */
virtual void open();
virtual void open(const string & sql);
/* as open, but with our query exept Sql */
virtual bool query(const char *query);
/* func. closes a query */
virtual void close(void);
/* Cancel changes, made in insert or edit states of dataset */
virtual void cancel();
/* sequence numbers */
virtual long nextid(const char *seq_name);
/* sequence numbers */
virtual int num_rows();
virtual bool bof();
virtual bool eof();
virtual void first();
virtual void last();
virtual void prev();
virtual void next();
/* Go to record No (starting with 0) */
virtual bool seek(int pos = 0);
virtual result_set *getResult();
void setNeedFieldType(bool need);
};
#endif

View file

@ -1,121 +0,0 @@
/***************************************************************************
stringhelper.cpp
(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.
***************************************************************************/
/**********************************************************************
* Copyright (c) 2002, Leo Seib, Hannover
*
* Project:SQLiteDataset C++ Dynamic Library
* Module: StringHelper class realisation file
* Author: Leo Seib E-Mail: lev@almaty.pointstrike.net
* Begin: 5/04/2002
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**********************************************************************/
#include "stringhelper.h"
str_helper::str_helper()
{
work_str = "";
}
str_helper::str_helper(const char *s)
{
work_str = s;
}
string str_helper::get_str()
{
return work_str;
}
void str_helper::set_str(const char *s)
{
work_str = s;
};
string str_helper::before(string s, bool & is_found)
{
is_found = false;
int pos = work_str.find(s);
int idx = pos + s.length();
is_found = pos >= 0;
if (idx == (int) work_str.length())
return work_str.substr(0, pos);
else
if ((pos >= 0)
&&
(!((work_str[idx] > 48 && work_str[idx] < 58)
|| (work_str[idx] > 64 && work_str[idx] < 91)
|| (work_str[idx] > 97 && work_str[idx] < 123)
|| work_str[idx] == 95)))
return work_str.substr(0, pos);
else //return (string)NULL;
{
string tmp("");
return tmp;
}
}
string str_helper::after(string s)
{
return work_str.substr(work_str.find(s) + s.length(), work_str.length());
}
string str_helper::replace(string pattern, string by_what)
{
bool is_found;
string bf = before(pattern, is_found);
string aft("");
string result("");
while (is_found)
{
aft = after(pattern);
result = bf + by_what + aft;
work_str.assign(result);
bf = before(pattern, is_found);
}
if (result.length() == 0)
result = work_str.c_str();
return result;
}

View file

@ -1,75 +0,0 @@
/***************************************************************************
stringhelper.h
(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.
***************************************************************************/
/**********************************************************************
* Copyright (c) 2002, Leo Seib, Hannover
*
* Project:SQLiteDataset C++ Dynamic Library
* Module: StringHelper class header file
* Author: Leo Seib E-Mail: lev@almaty.pointstrike.net
* Begin: 5/04/2002
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**********************************************************************/
using namespace std;
#include <string>
class str_helper
{
private:
string work_str;
public:
str_helper();
str_helper(const char *s);
~str_helper()
{
};
string get_str();
void set_str(const char *s);
string before(string s, bool & is_found);
string after(string s);
string replace(string pattern, string by_what);
};