2009-03-30 11:30 UTC+0200 Petr Chornyj (myorg63 at mail.ru)
* contrib/hbsqlit3/hbsqlit3.ch
* contrib/hbsqlit3/hbsqlit3.c
* Added support for sqlite_exec() callback.
Now the 3rd parameter is an optional callback that is invoked
once for each row of any query results.
* Now we can pass name of logfile as third parameter of
sqlite3_trace(), sqlite3_profile().
+ Added sqlite3_set_authorizer() -
Compile-Time Authorization Callbacks.
+ Added sqlite3_busy_handler() -
A Callback To Handle SQLITE_BUSY Errors.
+ Added sqlite3_progress_handler() - Query Progress Callbacks.
+ Added sqlite3_commit_hook(), sqlite3_rollback_hook() -
Commit And Rollback Notification Callbacks
+ Added sqlite3_backup_*() API for backups purposes.
+ Added sqlite3_initialize(), sqlite3_shutdown(), sqlite3_interrupt(),
sqlite3_status(), sqlite3_db_status(), sqlite3_stmt_status(),
sqlite3_sql(), sqlite3_extended_errcode(), sqlite3_threadsafe(),
sqlite3_memory_used(), sqlite3_memory_highwater().
! Fixed sqlite3_table_column_metadata().
- Temporary disabled sqlite3_db_handle().
* Minor changes, cleanup and formating.
+ contrib/hbsqlit3/tests/authorizer.prg
+ contrib/hbsqlit3/tests/backup.prg
+ contrib/hbsqlit3/tests/hooks.prg
+ Added for demonstration of new possibilities.
+ contrib/hbsqlit3/tests/metadata.prg
* Minor changes
This commit is contained in:
@@ -8,6 +8,36 @@
|
||||
2009-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org)
|
||||
*/
|
||||
|
||||
2009-03-30 11:30 UTC+0200 Petr Chornyj (myorg63 at mail.ru)
|
||||
* contrib/hbsqlit3/hbsqlit3.ch
|
||||
* contrib/hbsqlit3/hbsqlit3.c
|
||||
* Added support for sqlite_exec() callback.
|
||||
Now the 3rd parameter is an optional callback that is invoked
|
||||
once for each row of any query results.
|
||||
* Now we can pass name of logfile as third parameter of
|
||||
sqlite3_trace(), sqlite3_profile().
|
||||
+ Added sqlite3_set_authorizer() -
|
||||
Compile-Time Authorization Callbacks.
|
||||
+ Added sqlite3_busy_handler() -
|
||||
A Callback To Handle SQLITE_BUSY Errors.
|
||||
+ Added sqlite3_progress_handler() - Query Progress Callbacks.
|
||||
+ Added sqlite3_commit_hook(), sqlite3_rollback_hook() -
|
||||
Commit And Rollback Notification Callbacks
|
||||
+ Added sqlite3_backup_*() API for backups purposes.
|
||||
+ Added sqlite3_initialize(), sqlite3_shutdown(), sqlite3_interrupt(),
|
||||
sqlite3_status(), sqlite3_db_status(), sqlite3_stmt_status(),
|
||||
sqlite3_sql(), sqlite3_extended_errcode(), sqlite3_threadsafe(),
|
||||
sqlite3_memory_used(), sqlite3_memory_highwater().
|
||||
! Fixed sqlite3_table_column_metadata().
|
||||
- Temporary disabled sqlite3_db_handle().
|
||||
* Minor changes, cleanup and formating.
|
||||
+ contrib/hbsqlit3/tests/authorizer.prg
|
||||
+ contrib/hbsqlit3/tests/backup.prg
|
||||
+ contrib/hbsqlit3/tests/hooks.prg
|
||||
+ Added for demonstration of new possibilities.
|
||||
+ contrib/hbsqlit3/tests/metadata.prg
|
||||
* Minor changes
|
||||
|
||||
2009-03-30 10:01 UTC+0200 Viktor Szakats (harbour.01 syenar hu)
|
||||
* config/win/owatcom.cf
|
||||
* config/linux/owatcom.cf
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -47,7 +47,7 @@
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice.
|
||||
*
|
||||
* See COPYING for licensing terms.
|
||||
* See doc/license.txt for licensing terms.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -61,45 +61,44 @@
|
||||
#define SQLITE_INTEGER 1
|
||||
#define SQLITE_FLOAT 2
|
||||
#ifdef SQLITE_TEXT
|
||||
#undef SQLITE_TEXT
|
||||
#undef SQLITE_TEXT
|
||||
#else
|
||||
#define SQLITE_TEXT 3
|
||||
#define SQLITE_TEXT 3
|
||||
#endif
|
||||
#define SQLITE3_TEXT 3
|
||||
#define SQLITE_BLOB 4
|
||||
#define SQLITE_NULL 5
|
||||
|
||||
#define SQLITE_OK 0 /* Successful result */
|
||||
|
||||
#define SQLITE_OK 0 /* Successful result */
|
||||
/* Beginning-of-Error-Codes */
|
||||
#define SQLITE_ERROR 1 /* SQL error or missing database */
|
||||
#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */
|
||||
#define SQLITE_PERM 3 /* Access permission denied */
|
||||
#define SQLITE_ABORT 4 /* Callback routine requested an abort */
|
||||
#define SQLITE_BUSY 5 /* The database file is locked */
|
||||
#define SQLITE_LOCKED 6 /* A table in the database is locked */
|
||||
#define SQLITE_NOMEM 7 /* A malloc() failed */
|
||||
#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
|
||||
#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/
|
||||
#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
|
||||
#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
|
||||
#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */
|
||||
#define SQLITE_FULL 13 /* Insertion failed because database is full */
|
||||
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
|
||||
#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */
|
||||
#define SQLITE_EMPTY 16 /* Database is empty */
|
||||
#define SQLITE_SCHEMA 17 /* The database schema changed */
|
||||
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
|
||||
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
|
||||
#define SQLITE_MISMATCH 20 /* Data type mismatch */
|
||||
#define SQLITE_MISUSE 21 /* Library used incorrectly */
|
||||
#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
|
||||
#define SQLITE_AUTH 23 /* Authorization denied */
|
||||
#define SQLITE_FORMAT 24 /* Auxiliary database format error */
|
||||
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
|
||||
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
|
||||
#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
|
||||
#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
|
||||
#define SQLITE_ERROR 1 /* SQL error or missing database */
|
||||
#define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */
|
||||
#define SQLITE_PERM 3 /* Access permission denied */
|
||||
#define SQLITE_ABORT 4 /* Callback routine requested an abort */
|
||||
#define SQLITE_BUSY 5 /* The database file is locked */
|
||||
#define SQLITE_LOCKED 6 /* A table in the database is locked */
|
||||
#define SQLITE_NOMEM 7 /* A malloc() failed */
|
||||
#define SQLITE_READONLY 8 /* Attempt to write a readonly database */
|
||||
#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/
|
||||
#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
|
||||
#define SQLITE_CORRUPT 11 /* The database disk image is malformed */
|
||||
#define SQLITE_NOTFOUND 12 /* NOT USED. Table or record not found */
|
||||
#define SQLITE_FULL 13 /* Insertion failed because database is full */
|
||||
#define SQLITE_CANTOPEN 14 /* Unable to open the database file */
|
||||
#define SQLITE_PROTOCOL 15 /* NOT USED. Database lock protocol error */
|
||||
#define SQLITE_EMPTY 16 /* Database is empty */
|
||||
#define SQLITE_SCHEMA 17 /* The database schema changed */
|
||||
#define SQLITE_TOOBIG 18 /* String or BLOB exceeds size limit */
|
||||
#define SQLITE_CONSTRAINT 19 /* Abort due to constraint violation */
|
||||
#define SQLITE_MISMATCH 20 /* Data type mismatch */
|
||||
#define SQLITE_MISUSE 21 /* Library used incorrectly */
|
||||
#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */
|
||||
#define SQLITE_AUTH 23 /* Authorization denied */
|
||||
#define SQLITE_FORMAT 24 /* Auxiliary database format error */
|
||||
#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */
|
||||
#define SQLITE_NOTADB 26 /* File opened that is not a database file */
|
||||
#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */
|
||||
#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */
|
||||
/* End-of-Error-Codes */
|
||||
|
||||
/* Combination of the following bit values are used
|
||||
@@ -117,4 +116,59 @@
|
||||
#define SQLITE_OPEN_SUBJOURNAL 8192
|
||||
#define SQLITE_OPEN_MASTER_JOURNAL 16384
|
||||
|
||||
/* Status Parameters for prepared statements */
|
||||
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
|
||||
#define SQLITE_STMTSTATUS_SORT 2
|
||||
|
||||
/* Authorizer Action Codes */
|
||||
#define SQLITE_CREATE_INDEX 1 /* Index Name Table Name */
|
||||
#define SQLITE_CREATE_TABLE 2 /* Table Name NULL */
|
||||
#define SQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */
|
||||
#define SQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */
|
||||
#define SQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */
|
||||
#define SQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */
|
||||
#define SQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */
|
||||
#define SQLITE_CREATE_VIEW 8 /* View Name NULL */
|
||||
#define SQLITE_DELETE 9 /* Table Name NULL */
|
||||
#define SQLITE_DROP_INDEX 10 /* Index Name Table Name */
|
||||
#define SQLITE_DROP_TABLE 11 /* Table Name NULL */
|
||||
#define SQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */
|
||||
#define SQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */
|
||||
#define SQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */
|
||||
#define SQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */
|
||||
#define SQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */
|
||||
#define SQLITE_DROP_VIEW 17 /* View Name NULL */
|
||||
#define SQLITE_INSERT 18 /* Table Name NULL */
|
||||
#define SQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */
|
||||
#define SQLITE_READ 20 /* Table Name Column Name */
|
||||
#define SQLITE_SELECT 21 /* NULL NULL */
|
||||
#define SQLITE_TRANSACTION 22 /* Operation NULL */
|
||||
#define SQLITE_UPDATE 23 /* Table Name Column Name */
|
||||
#define SQLITE_ATTACH 24 /* Filename NULL */
|
||||
#define SQLITE_DETACH 25 /* Database Name NULL */
|
||||
#define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */
|
||||
#define SQLITE_REINDEX 27 /* Index Name NULL */
|
||||
#define SQLITE_ANALYZE 28 /* Table Name NULL */
|
||||
#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */
|
||||
#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */
|
||||
#define SQLITE_FUNCTION 31 /* NULL Function Name */
|
||||
#define SQLITE_SAVEPOINT 32 /* Operation Savepoint Name */
|
||||
|
||||
/* Authorizer Return Codes */
|
||||
#define SQLITE_DENY 1 /* Abort the SQL statement with an error */
|
||||
#define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
|
||||
|
||||
/* Status Parameters */
|
||||
#define SQLITE_STATUS_MEMORY_USED 0
|
||||
#define SQLITE_STATUS_PAGECACHE_USED 1
|
||||
#define SQLITE_STATUS_PAGECACHE_OVERFLOW 2
|
||||
#define SQLITE_STATUS_SCRATCH_USED 3
|
||||
#define SQLITE_STATUS_SCRATCH_OVERFLOW 4
|
||||
#define SQLITE_STATUS_MALLOC_SIZE 5
|
||||
#define SQLITE_STATUS_PARSER_STACK 6
|
||||
#define SQLITE_STATUS_PAGECACHE_SIZE 7
|
||||
#define SQLITE_STATUS_SCRATCH_SIZE 8
|
||||
|
||||
/* Status Parameters for database connections */
|
||||
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
|
||||
#endif
|
||||
|
||||
255
harbour/contrib/hbsqlit3/tests/authorizer.prg
Normal file
255
harbour/contrib/hbsqlit3/tests/authorizer.prg
Normal file
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* SQLite3 Demo. Using sqlite3_set_authorizer()
|
||||
*
|
||||
* Copyright 2009 P.Chornyj <myorg63@mail.ru>
|
||||
*
|
||||
* 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 software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
|
||||
*
|
||||
* As a special exception, the Harbour Project gives permission for
|
||||
* additional uses of the text contained in its release of Harbour.
|
||||
*
|
||||
* The exception is that, if you link the Harbour libraries with other
|
||||
* files to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the Harbour library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the Harbour
|
||||
* Project under the name Harbour. If you copy code from other
|
||||
* Harbour Project or Free Software Foundation releases into a copy of
|
||||
* Harbour, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for Harbour, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice.
|
||||
*
|
||||
* See COPYING for licensing terms.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Using sqlite3_set_authorizer()
|
||||
*
|
||||
* This routine registers a authorizer callback with a particular
|
||||
* database connection, supplied in the first argument.
|
||||
* The authorizer callback is invoked as SQL statements are being compiled
|
||||
* by sqlite3_prepare().
|
||||
*
|
||||
* When the callback returns SQLITE_OK, that means the operation requested
|
||||
* is ok.
|
||||
* When the callback returns SQLITE_DENY, the sqlite3_prepare() or
|
||||
* equivalent call that triggered the authorizer will fail with an error
|
||||
* message explaining that access is denied.
|
||||
* If the authorizer code is SQLITE_READ and the callback returns
|
||||
* SQLITE_IGNORE then the prepared statement statement is constructed to
|
||||
* substitute a NULL value in place of the table column that would have
|
||||
* been read if SQLITE_OK had been returned.
|
||||
* The SQLITE_IGNORE return can be used to deny an untrusted user access
|
||||
* to individual columns of a table.
|
||||
*
|
||||
* The first parameter to the authorizer callback is an integer
|
||||
* action code that specifies the particular action to be authorized.
|
||||
* The second through fourth parameters to the callback are strings
|
||||
* that contain additional details about the action to be authorized.
|
||||
*/
|
||||
|
||||
#include "common.ch"
|
||||
#include "hbsqlit3.ch"
|
||||
|
||||
FUNCTION main()
|
||||
LOCAL cFile := ":memory:", cSQLTEXT
|
||||
LOCAL pDb, cb
|
||||
//
|
||||
IF Empty( pDb := PrepareDB(cFile) )
|
||||
RETURN 1
|
||||
ENDIF
|
||||
// Authorizer1
|
||||
sqlite3_set_authorizer( pDb, @Authorizer() /*"Authorizer"*/ )
|
||||
|
||||
QOut( cSQLTEXT := "SELECT * FROM main.person WHERE age BETWEEN 20 AND 40" )
|
||||
cb := @CallBack() // "CallBack"
|
||||
Qout( cErrorMsg(sqlite3_exec(pDb, cSQLTEXT, cb)) )
|
||||
|
||||
sqlite3_sleep( 3000 )
|
||||
// Authorizer2
|
||||
Qout( cErrorMsg(sqlite3_set_authorizer(pDb, @Authorizer2() /*"Authorizer2"*/)) )
|
||||
|
||||
QOut( cSQLTEXT := "SELECT * FROM main.person WHERE age BETWEEN 20 AND 40" )
|
||||
Qout( cErrorMsg(sqlite3_exec(pDb, cSQLTEXT, cb)) )
|
||||
|
||||
sqlite3_sleep( 3000 )
|
||||
// Authorizer3
|
||||
Qout( cErrorMsg(sqlite3_set_authorizer(pDb, @Authorizer3() /*"Authorizer3"*/)) )
|
||||
|
||||
QOut( cSQLTEXT := "SELECT * FROM main.person WHERE age BETWEEN 20 AND 40" )
|
||||
Qout( cErrorMsg(sqlite3_exec(pDb, cSQLTEXT, cb), FALSE) )
|
||||
|
||||
sqlite3_sleep( 3000 )
|
||||
//
|
||||
pDb := Nil // close database
|
||||
//
|
||||
RETURN 0
|
||||
|
||||
/**
|
||||
*/
|
||||
FUNCTION Authorizer( nAction, cName1, cName2, cDatabaseName, cTriggerOrViewName )
|
||||
LOCAL oldColor := SetColor( "R/N" )
|
||||
//
|
||||
Qout( "=>", StrZero(nAction, 2), cName1, cName2, cDatabaseName, cTriggerOrViewName )
|
||||
|
||||
SetColor( oldColor )
|
||||
//
|
||||
RETURN SQLITE_OK
|
||||
|
||||
/**
|
||||
*/
|
||||
FUNCTION Authorizer2( nAction, cName1, cName2, cDatabaseName, cTriggerOrViewName )
|
||||
LOCAL oldColor := SetColor( "R/N" )
|
||||
//
|
||||
Qout( "=>", StrZero(nAction, 2), cName1, cName2, cDatabaseName, cTriggerOrViewName )
|
||||
|
||||
SetColor( oldColor )
|
||||
//
|
||||
RETURN iif( cName2 == "pasw", SQLITE_IGNORE, SQLITE_OK )
|
||||
|
||||
/**
|
||||
*/
|
||||
FUNCTION Authorizer3( nAction, cName1, cName2, cDatabaseName, cTriggerOrViewName )
|
||||
//
|
||||
RETURN iif( nAction == SQLITE_SELECT, SQLITE_DENY, SQLITE_OK )
|
||||
|
||||
/**
|
||||
*/
|
||||
FUNCTION CallBack( nColCount, aValue, aColName )
|
||||
LOCAL nI
|
||||
LOCAL oldColor := SetColor( "G/N" )
|
||||
//
|
||||
FOR nI := 1 TO nColCount
|
||||
Qout( Padr(aColName[nI], 5) , " == ", aValue[nI] )
|
||||
NEXT
|
||||
|
||||
SetColor( oldColor )
|
||||
//
|
||||
RETURN 0
|
||||
|
||||
/**
|
||||
*/
|
||||
STATIC FUNCTION cErrorMsg( nError, lShortMsg )
|
||||
LOCAL aErrorCodes := { ;
|
||||
{ SQLITE_ERROR , "SQLITE_ERROR" , "SQL error or missing database" }, ;
|
||||
{ SQLITE_INTERNAL , "SQLITE_INTERNAL" , "NOT USED. Internal logic error in SQLite" }, ;
|
||||
{ SQLITE_PERM , "SQLITE_PERM" , "Access permission denied" }, ;
|
||||
{ SQLITE_ABORT , "SQLITE_ABORT" , "Callback routine requested an abort" }, ;
|
||||
{ SQLITE_BUSY , "SQLITE_BUSY" , "The database file is locked" }, ;
|
||||
{ SQLITE_LOCKED , "SQLITE_LOCKED" , "A table in the database is locked" }, ;
|
||||
{ SQLITE_NOMEM , "SQLITE_NOMEM" , "A malloc() failed" }, ;
|
||||
{ SQLITE_READONLY , "SQLITE_READONLY" , "Attempt to write a readonly database" }, ;
|
||||
{ SQLITE_INTERRUPT , "SQLITE_INTERRUPT" , "Operation terminated by sqlite3_interrupt()" }, ;
|
||||
{ SQLITE_IOERR , "SQLITE_IOERR" , "Some kind of disk I/O error occurred" }, ;
|
||||
{ SQLITE_CORRUPT , "SQLITE_CORRUPT" , "The database disk image is malformed" }, ;
|
||||
{ SQLITE_NOTFOUND , "SQLITE_NOTFOUND" , "NOT USED. Table or record not found" }, ;
|
||||
{ SQLITE_FULL , "SQLITE_FULL" , "Insertion failed because database is full" }, ;
|
||||
{ SQLITE_CANTOPEN , "SQLITE_CANTOPEN" , "Unable to open the database file" }, ;
|
||||
{ SQLITE_PROTOCOL , "SQLITE_PROTOCOL" , "NOT USED. Database lock protocol error" }, ;
|
||||
{ SQLITE_EMPTY , "SQLITE_EMPTY" , "Database is empty" }, ;
|
||||
{ SQLITE_SCHEMA , "SQLITE_SCHEMA" , "The database schema changed" }, ;
|
||||
{ SQLITE_TOOBIG , "SQLITE_TOOBIG" , "String or BLOB exceeds size limit" }, ;
|
||||
{ SQLITE_CONSTRAINT , "SQLITE_CONSTRAINT" , "Abort due to constraint violation" }, ;
|
||||
{ SQLITE_MISMATCH , "SQLITE_MISMATCH" , "Data type mismatch" }, ;
|
||||
{ SQLITE_MISUSE , "SQLITE_MISUSE" , "Library used incorrectly" }, ;
|
||||
{ SQLITE_NOLFS , "SQLITE_NOLFS" , "Uses OS features not supported on host" }, ;
|
||||
{ SQLITE_AUTH , "SQLITE_AUTH" , "Authorization denied" }, ;
|
||||
{ SQLITE_FORMAT , "SQLITE_FORMAT" , "Auxiliary database format error" }, ;
|
||||
{ SQLITE_RANGE , "SQLITE_RANGE" , "2nd parameter to sqlite3_bind out of range" }, ;
|
||||
{ SQLITE_NOTADB , "SQLITE_NOTADB" , "File opened that is not a database file" }, ;
|
||||
{ SQLITE_ROW , "SQLITE_ROW" , "sqlite3_step() has another row ready" }, ;
|
||||
{ SQLITE_DONE , "SQLITE_DONE" , "sqlite3_step() has finished executing" } ;
|
||||
}, nIndex, cErrorMsg := "UNKNOWN"
|
||||
//
|
||||
DEFAULT lShortMsg TO TRUE
|
||||
|
||||
IF hb_IsNumeric( nError )
|
||||
IF nError == 0
|
||||
cErrorMsg := "SQLITE_OK"
|
||||
ELSE
|
||||
nIndex := AScan( aErrorCodes, {|x| x[1] == nError } )
|
||||
cErrorMsg := iif( nIndex > 0, aErrorCodes[ nIndex ][ iif(lShortMsg,2,3) ], cErrorMsg )
|
||||
ENDIF
|
||||
ENDIF
|
||||
//
|
||||
RETURN cErrorMsg
|
||||
|
||||
/**
|
||||
*/
|
||||
STATIC FUNCTION PrepareDB( cFile )
|
||||
LOCAL cSQLTEXT, cMsg
|
||||
LOCAL pDb, pStmt
|
||||
LOCAL hPerson := { ;
|
||||
"Bob" => 52, ;
|
||||
"Fred" => 32, ;
|
||||
"Sasha" => 17, ;
|
||||
"Andy" => 20, ;
|
||||
"Ivet" => 28 ;
|
||||
}, enum
|
||||
//
|
||||
pDb := sqlite3_open( cFile, TRUE )
|
||||
IF Empty( pDb )
|
||||
QOut( "Can't open/create database : ", cFile )
|
||||
|
||||
RETURN NIL
|
||||
ENDIF
|
||||
|
||||
cSQLTEXT := "CREATE TABLE person( name TEXT, age INTEGER, pasw TEXT(32) )"
|
||||
cMsg := cErrorMsg( sqlite3_exec(pDb, cSQLTEXT) )
|
||||
|
||||
IF cMsg <> "SQLITE_OK"
|
||||
QOut( "Can't create table : person" )
|
||||
pDb := NIL // close database
|
||||
|
||||
RETURN NIL
|
||||
ENDIF
|
||||
//
|
||||
cSQLTEXT := "INSERT INTO person( name, age, pasw ) VALUES( :name, :age, :pasw )"
|
||||
pStmt := sqlite3_prepare( pDb, cSQLTEXT )
|
||||
IF Empty( pStmt )
|
||||
QOut( "Can't prepare statement : ", cSQLTEXT )
|
||||
pDb := NIL
|
||||
|
||||
RETURN NIL
|
||||
ENDIF
|
||||
|
||||
FOR EACH enum IN hPerson
|
||||
sqlite3_reset( pStmt )
|
||||
sqlite3_bind_text( pStmt, 1, enum:__enumKey )
|
||||
sqlite3_bind_int( pStmt, 2, enum:__enumValue )
|
||||
sqlite3_bind_text( pStmt, 3, hb_md5(enum:__enumKey) )
|
||||
sqlite3_step( pStmt )
|
||||
NEXT
|
||||
|
||||
sqlite3_clear_bindings( pStmt )
|
||||
sqlite3_finalize( pStmt )
|
||||
//
|
||||
RETURN pDb
|
||||
236
harbour/contrib/hbsqlit3/tests/backup.prg
Normal file
236
harbour/contrib/hbsqlit3/tests/backup.prg
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* SQLite3 Demo. Using sqlite3_backup_*()
|
||||
*
|
||||
* Copyright 2009 P.Chornyj <myorg63@mail.ru>
|
||||
*
|
||||
* 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 software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
|
||||
*
|
||||
* As a special exception, the Harbour Project gives permission for
|
||||
* additional uses of the text contained in its release of Harbour.
|
||||
*
|
||||
* The exception is that, if you link the Harbour libraries with other
|
||||
* files to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the Harbour library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the Harbour
|
||||
* Project under the name Harbour. If you copy code from other
|
||||
* Harbour Project or Free Software Foundation releases into a copy of
|
||||
* Harbour, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for Harbour, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice.
|
||||
*
|
||||
* See COPYING for licensing terms.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Using sqlite3_backup_*()
|
||||
*
|
||||
* This API is used to overwrite the contents of one database with that
|
||||
* of another. It is useful either for creating backups of databases or
|
||||
* for copying in-memory databases to or from persistent files.
|
||||
*
|
||||
* sqlite3_backup_init() is called once to initialize the backup,
|
||||
* sqlite3_backup_step() is called one or more times to transfer the data
|
||||
* between the two databases, and finally
|
||||
* sqlite3_backup_finish() is called to release all resources associated
|
||||
* with the backup operation.
|
||||
*/
|
||||
|
||||
#include "common.ch"
|
||||
#include "hbsqlit3.ch"
|
||||
|
||||
FUNCTION main()
|
||||
LOCAL cFileSource := ":memory:", cFileDest := "backup.db", cSQLTEXT
|
||||
LOCAL pDbSource, pDbDest, pBackup, cb, nDbFlags
|
||||
//
|
||||
IF sqlite3_libversion_number() < 3006011
|
||||
RETURN 1
|
||||
ENDIF
|
||||
|
||||
IF Empty( pDbSource := PrepareDB(cFileSource) )
|
||||
RETURN 1
|
||||
ENDIF
|
||||
|
||||
nDbFlags := SQLITE_OPEN_CREATE + SQLITE_OPEN_READWRITE + ;
|
||||
SQLITE_OPEN_EXCLUSIVE
|
||||
pDbDest := sqlite3_open_v2( cFileDest, nDbFlags )
|
||||
|
||||
IF Empty( pDbDest )
|
||||
QOut( "Can't open database : ", cFileDest )
|
||||
|
||||
RETURN 1
|
||||
ENDIF
|
||||
|
||||
sqlite3_trace( pDbDest, TRUE, "backup.log" )
|
||||
|
||||
//
|
||||
pBackup := sqlite3_backup_init( pDbDest, "main", pDbSource, "main" )
|
||||
IF Empty( pBackup )
|
||||
QOut( "Can't initialize backup" )
|
||||
|
||||
RETURN 1
|
||||
ELSE
|
||||
QOut( "Start backup.." )
|
||||
ENDIF
|
||||
|
||||
IF sqlite3_backup_step(pBackup, -1) == SQLITE_DONE
|
||||
QOut( "Backup successful." )
|
||||
ENDIF
|
||||
|
||||
sqlite3_backup_finish( pBackup ) /* !!! */
|
||||
|
||||
pDbSource := Nil /* close :memory: database */
|
||||
|
||||
/* Little test for sqlite3_exec with callback */
|
||||
QOut( "" )
|
||||
QOut( cSQLTEXT := "SELECT * FROM main.person WHERE age BETWEEN 20 AND 40" )
|
||||
cb := @CallBack() // "CallBack"
|
||||
Qout( cErrorMsg(sqlite3_exec(pDbDest, cSQLTEXT, cb)) )
|
||||
|
||||
pDbDest := Nil // close database
|
||||
|
||||
sqlite3_sleep( 3000 )
|
||||
//
|
||||
RETURN 0
|
||||
|
||||
/**
|
||||
*/
|
||||
FUNCTION CallBack( nColCount, aValue, aColName )
|
||||
LOCAL nI
|
||||
LOCAL oldColor := SetColor( "G/N" )
|
||||
//
|
||||
FOR nI := 1 TO nColCount
|
||||
Qout( Padr(aColName[nI], 5) , " == ", aValue[nI] )
|
||||
NEXT
|
||||
|
||||
SetColor( oldColor )
|
||||
//
|
||||
RETURN 0
|
||||
|
||||
/**
|
||||
*/
|
||||
STATIC FUNCTION cErrorMsg( nError, lShortMsg )
|
||||
LOCAL aErrorCodes := { ;
|
||||
{ SQLITE_ERROR , "SQLITE_ERROR" , "SQL error or missing database" }, ;
|
||||
{ SQLITE_INTERNAL , "SQLITE_INTERNAL" , "NOT USED. Internal logic error in SQLite" }, ;
|
||||
{ SQLITE_PERM , "SQLITE_PERM" , "Access permission denied" }, ;
|
||||
{ SQLITE_ABORT , "SQLITE_ABORT" , "Callback routine requested an abort" }, ;
|
||||
{ SQLITE_BUSY , "SQLITE_BUSY" , "The database file is locked" }, ;
|
||||
{ SQLITE_LOCKED , "SQLITE_LOCKED" , "A table in the database is locked" }, ;
|
||||
{ SQLITE_NOMEM , "SQLITE_NOMEM" , "A malloc() failed" }, ;
|
||||
{ SQLITE_READONLY , "SQLITE_READONLY" , "Attempt to write a readonly database" }, ;
|
||||
{ SQLITE_INTERRUPT , "SQLITE_INTERRUPT" , "Operation terminated by sqlite3_interrupt()" }, ;
|
||||
{ SQLITE_IOERR , "SQLITE_IOERR" , "Some kind of disk I/O error occurred" }, ;
|
||||
{ SQLITE_CORRUPT , "SQLITE_CORRUPT" , "The database disk image is malformed" }, ;
|
||||
{ SQLITE_NOTFOUND , "SQLITE_NOTFOUND" , "NOT USED. Table or record not found" }, ;
|
||||
{ SQLITE_FULL , "SQLITE_FULL" , "Insertion failed because database is full" }, ;
|
||||
{ SQLITE_CANTOPEN , "SQLITE_CANTOPEN" , "Unable to open the database file" }, ;
|
||||
{ SQLITE_PROTOCOL , "SQLITE_PROTOCOL" , "NOT USED. Database lock protocol error" }, ;
|
||||
{ SQLITE_EMPTY , "SQLITE_EMPTY" , "Database is empty" }, ;
|
||||
{ SQLITE_SCHEMA , "SQLITE_SCHEMA" , "The database schema changed" }, ;
|
||||
{ SQLITE_TOOBIG , "SQLITE_TOOBIG" , "String or BLOB exceeds size limit" }, ;
|
||||
{ SQLITE_CONSTRAINT , "SQLITE_CONSTRAINT" , "Abort due to constraint violation" }, ;
|
||||
{ SQLITE_MISMATCH , "SQLITE_MISMATCH" , "Data type mismatch" }, ;
|
||||
{ SQLITE_MISUSE , "SQLITE_MISUSE" , "Library used incorrectly" }, ;
|
||||
{ SQLITE_NOLFS , "SQLITE_NOLFS" , "Uses OS features not supported on host" }, ;
|
||||
{ SQLITE_AUTH , "SQLITE_AUTH" , "Authorization denied" }, ;
|
||||
{ SQLITE_FORMAT , "SQLITE_FORMAT" , "Auxiliary database format error" }, ;
|
||||
{ SQLITE_RANGE , "SQLITE_RANGE" , "2nd parameter to sqlite3_bind out of range" }, ;
|
||||
{ SQLITE_NOTADB , "SQLITE_NOTADB" , "File opened that is not a database file" }, ;
|
||||
{ SQLITE_ROW , "SQLITE_ROW" , "sqlite3_step() has another row ready" }, ;
|
||||
{ SQLITE_DONE , "SQLITE_DONE" , "sqlite3_step() has finished executing" } ;
|
||||
}, nIndex, cErrorMsg := "UNKNOWN"
|
||||
//
|
||||
DEFAULT lShortMsg TO TRUE
|
||||
|
||||
IF hb_IsNumeric( nError )
|
||||
IF nError == 0
|
||||
cErrorMsg := "SQLITE_OK"
|
||||
ELSE
|
||||
nIndex := AScan( aErrorCodes, {|x| x[1] == nError } )
|
||||
cErrorMsg := iif( nIndex > 0, aErrorCodes[ nIndex ][ iif(lShortMsg,2,3) ], cErrorMsg )
|
||||
ENDIF
|
||||
ENDIF
|
||||
//
|
||||
RETURN cErrorMsg
|
||||
|
||||
/**
|
||||
*/
|
||||
STATIC FUNCTION PrepareDB( cFile )
|
||||
LOCAL cSQLTEXT, cMsg
|
||||
LOCAL pDb, pStmt
|
||||
LOCAL hPerson := { ;
|
||||
"Bob" => 52, ;
|
||||
"Fred" => 32, ;
|
||||
"Sasha" => 17, ;
|
||||
"Andy" => 20, ;
|
||||
"Ivet" => 28 ;
|
||||
}, enum
|
||||
//
|
||||
pDb := sqlite3_open( cFile, TRUE )
|
||||
IF Empty( pDb )
|
||||
QOut( "Can't open/create database : ", cFile )
|
||||
|
||||
RETURN NIL
|
||||
ENDIF
|
||||
|
||||
sqlite3_trace( pDb, TRUE, "backup.log" )
|
||||
|
||||
cSQLTEXT := "CREATE TABLE person( name TEXT, age INTEGER )"
|
||||
cMsg := cErrorMsg( sqlite3_exec(pDb, cSQLTEXT) )
|
||||
|
||||
IF cMsg <> "SQLITE_OK"
|
||||
QOut( "Can't create table : person" )
|
||||
pDb := NIL // close database
|
||||
|
||||
RETURN NIL
|
||||
ENDIF
|
||||
//
|
||||
cSQLTEXT := "INSERT INTO person( name, age ) VALUES( :name, :age )"
|
||||
pStmt := sqlite3_prepare( pDb, cSQLTEXT )
|
||||
IF Empty( pStmt )
|
||||
QOut( "Can't prepare statement : ", cSQLTEXT )
|
||||
pDb := NIL
|
||||
|
||||
RETURN NIL
|
||||
ENDIF
|
||||
|
||||
FOR EACH enum IN hPerson
|
||||
sqlite3_reset( pStmt )
|
||||
sqlite3_bind_text( pStmt, 1, enum:__enumKey )
|
||||
sqlite3_bind_int( pStmt, 2, enum:__enumValue )
|
||||
sqlite3_step( pStmt )
|
||||
NEXT
|
||||
|
||||
sqlite3_clear_bindings( pStmt )
|
||||
sqlite3_finalize( pStmt )
|
||||
//
|
||||
RETURN pDb
|
||||
251
harbour/contrib/hbsqlit3/tests/hooks.prg
Normal file
251
harbour/contrib/hbsqlit3/tests/hooks.prg
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* SQLite3 Demo. Using sqlite3_commit_hook(), sqlite3_rollback_hook()
|
||||
*
|
||||
* Copyright 2009 P.Chornyj <myorg63@mail.ru>
|
||||
*
|
||||
* 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 software; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
|
||||
*
|
||||
* As a special exception, the Harbour Project gives permission for
|
||||
* additional uses of the text contained in its release of Harbour.
|
||||
*
|
||||
* The exception is that, if you link the Harbour libraries with other
|
||||
* files to produce an executable, this does not by itself cause the
|
||||
* resulting executable to be covered by the GNU General Public License.
|
||||
* Your use of that executable is in no way restricted on account of
|
||||
* linking the Harbour library code into it.
|
||||
*
|
||||
* This exception does not however invalidate any other reasons why
|
||||
* the executable file might be covered by the GNU General Public License.
|
||||
*
|
||||
* This exception applies only to the code released by the Harbour
|
||||
* Project under the name Harbour. If you copy code from other
|
||||
* Harbour Project or Free Software Foundation releases into a copy of
|
||||
* Harbour, as the General Public License permits, the exception does
|
||||
* not apply to the code that you add in this way. To avoid misleading
|
||||
* anyone as to the status of such modified files, you must delete
|
||||
* this exception notice from them.
|
||||
*
|
||||
* If you write modifications of your own for Harbour, it is your choice
|
||||
* whether to permit this exception to apply to your modifications.
|
||||
* If you do not wish that, delete this exception notice.
|
||||
*
|
||||
* See COPYING for licensing terms.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.ch"
|
||||
#include "hbsqlit3.ch"
|
||||
|
||||
FUNCTION main()
|
||||
LOCAL cSQLTEXT, cFile := ":memory:"
|
||||
LOCAL pDb, cb := @CallBack()
|
||||
//
|
||||
IF Empty( pDb := PrepareDB(cFile) )
|
||||
RETURN 1
|
||||
ENDIF
|
||||
//
|
||||
sqlite3_commit_hook( pDb, "HookCommitY" )
|
||||
|
||||
QOut( cSQLTEXT := "SELECT * FROM person WHERE name == 'Andy'" )
|
||||
Qout( "return value: ", cErrorMsg(sqlite3_exec(pDb, cSQLTEXT, cb)) )
|
||||
|
||||
QOut( cSQLTEXT := "BEGIN EXCLUSIVE TRANSACTION" )
|
||||
Qout( "return value: ",cErrorMsg(sqlite3_exec(pDb, cSQLTEXT)) )
|
||||
|
||||
QOut( cSQLTEXT := "DELETE FROM person WHERE name == 'Andy'" )
|
||||
Qout( "return value: ", cErrorMsg(sqlite3_exec(pDb, cSQLTEXT)) )
|
||||
|
||||
QOut( cSQLTEXT := "END TRANSACTION" )
|
||||
Qout( "return value: ", cErrorMsg(sqlite3_exec(pDb, cSQLTEXT)) )
|
||||
|
||||
QOut( cSQLTEXT := "SELECT * FROM person WHERE name == 'Andy'" )
|
||||
Qout( "return value: ", cErrorMsg(sqlite3_exec(pDb, cSQLTEXT, cb)) )
|
||||
|
||||
QOut( Replicate("-", Len(cSQLTEXT)) )
|
||||
|
||||
sqlite3_sleep( 10000 )
|
||||
//
|
||||
sqlite3_commit_hook( pDb, @HookCommitN() )
|
||||
sqlite3_rollback_hook( pDb, @HookRollback() )
|
||||
|
||||
QOut( cSQLTEXT := "SELECT * FROM person WHERE name == 'Ivet'" )
|
||||
Qout( "return value: ", cErrorMsg(sqlite3_exec(pDb, cSQLTEXT, cb)) )
|
||||
|
||||
QOut( cSQLTEXT := "BEGIN EXCLUSIVE TRANSACTION" )
|
||||
Qout( "return value: ", cErrorMsg(sqlite3_exec(pDb, cSQLTEXT)) )
|
||||
|
||||
QOut( cSQLTEXT := "DELETE FROM person WHERE name == 'Ivet'" )
|
||||
Qout( "return value: ", cErrorMsg(sqlite3_exec(pDb, cSQLTEXT)) )
|
||||
|
||||
QOut( cSQLTEXT := "END TRANSACTION" )
|
||||
Qout( "return value: ", cErrorMsg(sqlite3_exec(pDb, cSQLTEXT)) )
|
||||
|
||||
QOut( cSQLTEXT := "SELECT * FROM person WHERE name == 'Ivet'" )
|
||||
Qout( "return value: ", cErrorMsg(sqlite3_exec(pDb, cSQLTEXT, cb)) )
|
||||
//
|
||||
pDb := NIL
|
||||
|
||||
sqlite3_sleep( 10000 )
|
||||
//
|
||||
RETURN 0
|
||||
|
||||
/**
|
||||
*/
|
||||
FUNCTION CallBack( nColCount, aValue, aColName )
|
||||
LOCAL nI
|
||||
LOCAL oldColor := SetColor( "G/N" )
|
||||
//
|
||||
FOR nI := 1 TO nColCount
|
||||
Qout( Padr(aColName[nI], 5) , " == ", aValue[nI] )
|
||||
NEXT
|
||||
|
||||
SetColor( oldColor )
|
||||
//
|
||||
RETURN 0
|
||||
|
||||
/**
|
||||
*/
|
||||
FUNCTION HookCommitY()
|
||||
LOCAL oldColor := SetColor( "R+/N" )
|
||||
//
|
||||
Qout( "!! COMMIT" )
|
||||
|
||||
SetColor( oldColor )
|
||||
//
|
||||
RETURN 0
|
||||
|
||||
FUNCTION HookCommitN()
|
||||
LOCAL oldColor := SetColor( "B+/N" )
|
||||
//
|
||||
Qout( "?? COMMIT or ROLLBACK" )
|
||||
|
||||
SetColor( oldColor )
|
||||
//
|
||||
RETURN 1 // not 0
|
||||
|
||||
FUNCTION HookRollback()
|
||||
LOCAL oldColor := SetColor( "R+/N" )
|
||||
//
|
||||
Qout( "!! ROLLBACK" )
|
||||
|
||||
SetColor( oldColor )
|
||||
//
|
||||
RETURN 1
|
||||
|
||||
/**
|
||||
*/
|
||||
STATIC FUNCTION cErrorMsg( nError, lShortMsg )
|
||||
LOCAL aErrorCodes := { ;
|
||||
{ SQLITE_ERROR , "SQLITE_ERROR" , "SQL error or missing database" }, ;
|
||||
{ SQLITE_INTERNAL , "SQLITE_INTERNAL" , "NOT USED. Internal logic error in SQLite" }, ;
|
||||
{ SQLITE_PERM , "SQLITE_PERM" , "Access permission denied" }, ;
|
||||
{ SQLITE_ABORT , "SQLITE_ABORT" , "Callback routine requested an abort" }, ;
|
||||
{ SQLITE_BUSY , "SQLITE_BUSY" , "The database file is locked" }, ;
|
||||
{ SQLITE_LOCKED , "SQLITE_LOCKED" , "A table in the database is locked" }, ;
|
||||
{ SQLITE_NOMEM , "SQLITE_NOMEM" , "A malloc() failed" }, ;
|
||||
{ SQLITE_READONLY , "SQLITE_READONLY" , "Attempt to write a readonly database" }, ;
|
||||
{ SQLITE_INTERRUPT , "SQLITE_INTERRUPT" , "Operation terminated by sqlite3_interrupt()" }, ;
|
||||
{ SQLITE_IOERR , "SQLITE_IOERR" , "Some kind of disk I/O error occurred" }, ;
|
||||
{ SQLITE_CORRUPT , "SQLITE_CORRUPT" , "The database disk image is malformed" }, ;
|
||||
{ SQLITE_NOTFOUND , "SQLITE_NOTFOUND" , "NOT USED. Table or record not found" }, ;
|
||||
{ SQLITE_FULL , "SQLITE_FULL" , "Insertion failed because database is full" }, ;
|
||||
{ SQLITE_CANTOPEN , "SQLITE_CANTOPEN" , "Unable to open the database file" }, ;
|
||||
{ SQLITE_PROTOCOL , "SQLITE_PROTOCOL" , "NOT USED. Database lock protocol error" }, ;
|
||||
{ SQLITE_EMPTY , "SQLITE_EMPTY" , "Database is empty" }, ;
|
||||
{ SQLITE_SCHEMA , "SQLITE_SCHEMA" , "The database schema changed" }, ;
|
||||
{ SQLITE_TOOBIG , "SQLITE_TOOBIG" , "String or BLOB exceeds size limit" }, ;
|
||||
{ SQLITE_CONSTRAINT , "SQLITE_CONSTRAINT" , "Abort due to constraint violation" }, ;
|
||||
{ SQLITE_MISMATCH , "SQLITE_MISMATCH" , "Data type mismatch" }, ;
|
||||
{ SQLITE_MISUSE , "SQLITE_MISUSE" , "Library used incorrectly" }, ;
|
||||
{ SQLITE_NOLFS , "SQLITE_NOLFS" , "Uses OS features not supported on host" }, ;
|
||||
{ SQLITE_AUTH , "SQLITE_AUTH" , "Authorization denied" }, ;
|
||||
{ SQLITE_FORMAT , "SQLITE_FORMAT" , "Auxiliary database format error" }, ;
|
||||
{ SQLITE_RANGE , "SQLITE_RANGE" , "2nd parameter to sqlite3_bind out of range" }, ;
|
||||
{ SQLITE_NOTADB , "SQLITE_NOTADB" , "File opened that is not a database file" }, ;
|
||||
{ SQLITE_ROW , "SQLITE_ROW" , "sqlite3_step() has another row ready" }, ;
|
||||
{ SQLITE_DONE , "SQLITE_DONE" , "sqlite3_step() has finished executing" } ;
|
||||
}, nIndex, cErrorMsg := "UNKNOWN"
|
||||
//
|
||||
DEFAULT lShortMsg TO TRUE
|
||||
|
||||
IF hb_IsNumeric( nError )
|
||||
IF nError == 0
|
||||
cErrorMsg := "SQLITE_OK"
|
||||
ELSE
|
||||
nIndex := AScan( aErrorCodes, {|x| x[1] == nError } )
|
||||
cErrorMsg := iif( nIndex > 0, aErrorCodes[ nIndex ][ iif(lShortMsg,2,3) ], cErrorMsg )
|
||||
ENDIF
|
||||
ENDIF
|
||||
//
|
||||
RETURN cErrorMsg
|
||||
|
||||
/**
|
||||
*/
|
||||
STATIC FUNCTION PrepareDB( cFile )
|
||||
LOCAL cSQLTEXT, cMsg
|
||||
LOCAL pDb, pStmt
|
||||
LOCAL hPerson := { ;
|
||||
"Bob" => 52, ;
|
||||
"Fred" => 32, ;
|
||||
"Sasha" => 17, ;
|
||||
"Andy" => 20, ;
|
||||
"Ivet" => 28 ;
|
||||
}, enum
|
||||
//
|
||||
pDb := sqlite3_open( cFile, TRUE )
|
||||
IF Empty( pDb )
|
||||
QOut( "Can't open/create database : ", cFile )
|
||||
|
||||
RETURN NIL
|
||||
ENDIF
|
||||
|
||||
Qout( cSQLTEXT := "CREATE TABLE person( name TEXT, age INTEGER )" )
|
||||
cMsg := cErrorMsg( sqlite3_exec(pDb, cSQLTEXT) )
|
||||
|
||||
IF cMsg <> "SQLITE_OK"
|
||||
QOut( "Can't create table : person" )
|
||||
pDb := NIL // close database
|
||||
|
||||
RETURN NIL
|
||||
ENDIF
|
||||
//
|
||||
cSQLTEXT := "INSERT INTO person( name, age ) VALUES( :name, :age )"
|
||||
pStmt := sqlite3_prepare( pDb, cSQLTEXT )
|
||||
IF Empty( pStmt )
|
||||
QOut( "Can't prepare statement : ", cSQLTEXT )
|
||||
pDb := NIL
|
||||
|
||||
RETURN NIL
|
||||
ENDIF
|
||||
|
||||
QOut( sqlite3_sql(pStmt) )
|
||||
QOut( Replicate("-", Len(cSQLTEXT)) )
|
||||
|
||||
FOR EACH enum IN hPerson
|
||||
sqlite3_reset( pStmt )
|
||||
sqlite3_bind_text( pStmt, 1, enum:__enumKey )
|
||||
sqlite3_bind_int( pStmt, 2, enum:__enumValue )
|
||||
sqlite3_step( pStmt )
|
||||
NEXT
|
||||
|
||||
sqlite3_clear_bindings( pStmt )
|
||||
sqlite3_finalize( pStmt )
|
||||
//
|
||||
RETURN pDb
|
||||
@@ -52,9 +52,7 @@
|
||||
|
||||
#include "hbsqlit3.ch"
|
||||
|
||||
#ifdef NODLL
|
||||
#define SQLITE_ENABLE_COLUMN_METADATA
|
||||
#endif
|
||||
//#define SQLITE_ENABLE_COLUMN_METADATA
|
||||
|
||||
PROCEDURE main()
|
||||
LOCAL lCreateIfNotExist := .f.
|
||||
|
||||
Reference in New Issue
Block a user