SQLite3 BaseFunction-Include - Invalid Memory
Verfasst: 14.12.2007 15:12
Nachdem ich des öfteren unerklärliche Speicherfehler (Prototype?!?) hatte, habe ich das Include etwas umgeschrieben und es scheint jetzt deutlich stabiler zu laufen. Falls jemand ähnliche Probleme hat, kann er es ja mal mit dieser geänderten Version probieren.
SQLite3_Include.pbi
SQLite3_Include.pbi
Code: Alles auswählen
; SQLite3 Include for Windows, Linux and MacOS
; based on a example by MLK
; binding functions based on code by Kiffi (PBOSL)
; tested with Ansi and Unicode under WinXP and XUbuntu
; Autor: ts-soft
; Changes: Thorsten1867 ('Prototypes' removed)
Enumeration
#SQLITE3_OK = 0 ; Successful Result
#SQLITE3_ERROR = 1 ; SQL error Or missing database
#SQLITE3_INTERNAL = 2 ; An internal logic error in SQLite
#SQLITE3_PERM = 3 ; Access permission denied
#SQLITE3_ABORT = 4 ; Callback routine requested An abort
#SQLITE3_BUSY = 5 ; The database file is locked
#SQLITE3_LOCKED = 6 ; A table in The database is locked
#SQLITE3_NOMEM = 7 ; A malloc() failed
#SQLITE3_READONLY = 8 ; Attempt To write A readonly database
#SQLITE3_INTERRUPT = 9 ; Operation terminated by SQLite_Interrupt()
#SQLITE3_IOERR = 10 ; Some kind of disk I/O error occurred
#SQLITE3_CORRUPT = 11 ; The database disk image is malformed
#SQLITE3_NOTFOUND = 12 ; (internal Only) table Or record not found
#SQLITE3_FULL = 13 ; Insertion failed because database is full
#SQLITE3_CANTOPEN = 14 ; Unable To open The database file
#SQLITE3_PROTOCOL = 15 ; database lock protocol error
#SQLITE3_EMPTY = 16 ; (internal Only) database table is empty
#SQLITE3_SCHEMA = 17 ; The database schema changed
#SQLITE3_TOOBIG = 18 ; Too much Data For one Row of A table
#SQLITE3_CONSTRAINT = 19 ; abort due To contraint violation
#SQLITE3_MISMATCH = 20 ; Data type mismatch
#SQLITE3_MISUSE = 21 ; Library used incorrectly
#SQLITE3_NOLFS = 22 ; Uses OS features not supported on host
#SQLITE3_AUTH = 23 ; Authorization denied
#SQLITE3_ROW = 100 ; sqlite_step() has another Row ready
#SQLITE3_DONE = 101 ; sqlite_step() has finished executing
#SQLITE3_STATIC = 0
#SQLITE_TRANSIENT = -1
#SQLITE_INTEGER = 1
#SQLITE_FLOAT = 2
#SQLITE_TEXT = 3
#SQLITE_BLOB = 4
#SQLITE_NULL = 5
EndEnumeration
Structure SQ3_Functions
DLL.l
IsASCII.b
PeekMode.l
close.l
errcode.l
errmsg.l
errmsg16.l
exec.l
exec_a.l
free_table.l
get_table.l
get_table_a.l
libversion.l
open.l
open16.l
last_insert_rowid.l
last_message.s
EndStructure
Structure SQ3_TABLEMAP
Table.l
Rows.l
Cols.l
RowPos.l
ColPos.l
EndStructure
Global SQ3.SQ3_Functions
Procedure.s UTF8(String$)
Protected Laenge.l, Result$, *MemoryID
Laenge = StringByteLength(String$, #PB_UTF8)
*MemoryID = AllocateMemory(Laenge+1)
PokeS(*MemoryID, String$, Laenge, #PB_UTF8)
Result$ = PeekS(*MemoryID)
FreeMemory(*MemoryID)
ProcedureReturn Result$
EndProcedure
; === SQL-Befehle ===
Procedure.l SQLiteEnd()
If SQ3\DLL
CloseLibrary(SQ3\DLL)
SQ3\DLL = #False
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteInit(sqlite3lib.s = "")
If sqlite3lib <> ""
SQ3\DLL = OpenLibrary(#PB_Any, sqlite3lib)
Else
CompilerSelect #PB_Compiler_OS
CompilerCase #PB_OS_Windows
SQ3\DLL = OpenLibrary(#PB_Any, "sqlite3.dll")
CompilerCase #PB_OS_Linux
SQ3\DLL = OpenLibrary(#PB_Any, "libsqlite3.so")
CompilerCase #PB_OS_MacOS
SQ3\DLL = OpenLibrary(#PB_Any, "/usr/lib/libsqlite3.dylib")
CompilerDefault
ProcedureReturn #False
CompilerEndSelect
EndIf
If SQ3\DLL
SQ3\close = GetFunction(SQ3\DLL, "sqlite3_close")
SQ3\errcode = GetFunction(SQ3\DLL, "sqlite3_errcode")
SQ3\errmsg = GetFunction(SQ3\DLL, "sqlite3_errmsg")
SQ3\errmsg16 = GetFunction(SQ3\DLL, "sqlite3_errmsg16")
SQ3\exec = GetFunction(SQ3\DLL, "sqlite3_exec")
SQ3\exec_a = GetFunction(SQ3\DLL, "sqlite3_exec")
SQ3\free_table = GetFunction(SQ3\DLL, "sqlite3_free_table")
SQ3\get_table = GetFunction(SQ3\DLL, "sqlite3_get_table")
SQ3\get_table_a = GetFunction(SQ3\DLL, "sqlite3_get_table")
SQ3\libversion = GetFunction(SQ3\DLL, "sqlite3_libversion")
SQ3\open = GetFunction(SQ3\DLL, "sqlite3_open")
SQ3\open16 = GetFunction(SQ3\DLL, "sqlite3_open16")
SQ3\last_insert_rowid = GetFunction(SQ3\DLL, "sqlite3_last_insert_rowid")
SQ3\PeekMode = #PB_UTF8
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteClose(hDB.l)
If Not hDB
SQ3\last_message = "Invalid Database Handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteClose)"
ProcedureReturn #False
EndIf
If SQ3\close
If CallCFunctionFast(SQ3\close, hDB) = #SQLITE3_OK
ProcedureReturn #True
EndIf
Else
SQ3\last_message = "Couldn't close Database"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteClose)"
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteOpen(FileName.s, AsciiMode.l = #False)
Protected hDB.l
CompilerIf #PB_Compiler_Unicode
If SQ3\open16
If CallCFunctionFast(SQ3\open16, FileName, @hDB) = #SQLITE3_OK
SQ3\last_message = "OK"
ProcedureReturn hDB
EndIf
EndIf
CompilerElse
If AsciiMode
SQ3\IsASCII = #True
SQ3\PeekMode = #PB_Ascii
EndIf
If SQ3\open
If CallCFunctionFast(SQ3\open, FileName, @hDB) = #SQLITE3_OK
SQ3\last_message = "OK"
ProcedureReturn hDB
EndIf
EndIf
CompilerEndIf
SQ3\last_message = "Couldn't open Database"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteOpen)"
ProcedureReturn #False
EndProcedure
ProcedureDLL.s SQLiteGetLastMessage()
ProcedureReturn SQ3\last_message
EndProcedure
Procedure.l SQLiteErrorCode(hDB.l)
If Not hDB
SQ3\last_message = "Invalid Database Handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteErrorCode)"
ProcedureReturn 1
EndIf
If SQ3\errcode
ProcedureReturn CallCFunctionFast(SQ3\errcode, hDB)
EndIf
ProcedureReturn -1
EndProcedure
Procedure.s SQLiteErrorMsg(hDB.l)
If Not hDB
SQ3\last_message = "Invalid Database Handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteErrorMsg)"
ProcedureReturn SQ3\last_message
EndIf
CompilerIf #PB_Compiler_Unicode
If SQ3\errmsg16
SQ3\last_message = PeekS(CallCFunctionFast(SQ3\errmsg16, hDB))
ProcedureReturn SQ3\last_message
EndIf
CompilerElse
If SQ3\errmsg
SQ3\last_message = PeekS(CallCFunctionFast(SQ3\errmsg, hDB))
ProcedureReturn SQ3\last_message
EndIf
CompilerEndIf
ProcedureReturn ""
EndProcedure
Procedure.s SQLiteLibversion()
If SQ3\libversion
SQ3\last_message = PeekS(CallCFunctionFast(SQ3\libversion), #PB_Any, #PB_Ascii)
ProcedureReturn SQ3\last_message
EndIf
EndProcedure
Procedure.l SQLiteExecute(hDB.l, Statement.s, callback.l = 0, cbpara.l = 0)
Protected result.l = 0, ReturnValue = 0
If Not hDB
SQ3\last_message = "Invalid Database Handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteExecute)"
ProcedureReturn #False
EndIf
If SQ3\IsASCII
If SQ3\exec_a
If CallCFunctionFast(SQ3\exec_a, hDB, Statement, callback, cbpara, @ReturnValue) = #SQLITE3_OK
SQ3\last_message = "OK"
ProcedureReturn #True
Else
CallCFunctionFast(SQ3\errmsg, @ReturnValue)
SQ3\last_message = PeekS(ReturnValue)
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteExecute)"
ProcedureReturn #False
EndIf
EndIf
Else
If SQ3\exec
If CallCFunctionFast(SQ3\exec, hDB, UTF8(Statement), callback, cbpara, @ReturnValue) = #SQLITE3_OK
SQ3\last_message = "OK"
ProcedureReturn #True
Else
CallCFunctionFast(SQ3\errmsg, @ReturnValue)
SQ3\last_message = PeekS(ReturnValue)
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteExecute)"
ProcedureReturn #False
EndIf
EndIf
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteLastInsertRowId(hDB.l)
If Not hDB
SQ3\last_message = "Invalid Database Handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteLastInsertRowId)"
ProcedureReturn #False
EndIf
If SQ3\last_insert_rowid
ProcedureReturn CallCFunctionFast(SQ3\last_insert_rowid, hDB)
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQliteFreeTable(*table.SQ3_TABLEMAP)
If SQ3\free_table
If *table\Table <> 0
CallCFunctionFast(SQ3\free_table, *table\Table)
*table\Table = 0
ProcedureReturn #True
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQliteFreeTable)"
EndIf
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteGetTable(hDB.l, Statement.s, *table.SQ3_TABLEMAP)
Protected nRow.l = 0, nColumn.l = 0, lResultPtr.l = 0, result.l = 0, ReturnValue = 0
If Not hDB
SQ3\last_message = "Invalid Database Handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteGetTable)"
ProcedureReturn #False
EndIf
If SQ3\get_table
*table\Table = 0
If SQ3\IsASCII
result = CallCFunctionFast(SQ3\get_table_a, hDB, Statement, @lResultPtr, @nRow, @nColumn, @ReturnValue)
Else
result = CallCFunctionFast(SQ3\get_table, hDB, UTF8(Statement), @lResultPtr, @nRow, @nColumn, @ReturnValue)
EndIf
If result = #SQLITE3_OK
*table\Table = lResultPtr
*table\Rows = nRow
*table\Cols = nColumn
*table\RowPos = 0
*table\ColPos = 0
SQ3\last_message = "OK"
ProcedureReturn *table
Else
CallCFunctionFast(SQ3\errmsg, @ReturnValue)
SQ3\last_message = PeekS(ReturnValue)
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteGetTable)"
ProcedureReturn #False
EndIf
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteNextRow(*table.SQ3_TABLEMAP)
If *table\Table <> 0
If *table\RowPos < *table\Rows
*table\RowPos + 1
ProcedureReturn #True
EndIf
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteNextRow)"
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteNextCol(*table.SQ3_TABLEMAP)
If *table\Table <> 0
If *table\ColPos < *table\Cols
*table\ColPos + 1
ProcedureReturn #True
Else
*table\ColPos = 0
EndIf
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteNextCol)"
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteSelectRow(*table.SQ3_TABLEMAP, Row.l)
If *table\Table <> 0
If Row > 0 And Row <= *table\Rows
*table\RowPos = Row
ProcedureReturn #True
EndIf
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteSelectRow)"
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteSelectCol(*table.SQ3_TABLEMAP, Col.l)
If *table\Table <> 0
If Col > 0 And Col <= *table\Cols
*table\ColPos = Col
ProcedureReturn #True
EndIf
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteSelectCol)"
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteSelectPos(*table.SQ3_TABLEMAP, Row.l, Col.l)
If *table\Table <> 0
If Row > 0 And Row <= *table\Rows And Col > 0 And Col <= *table\Cols
*table\RowPos = Row
*table\ColPos = Col
ProcedureReturn #True
EndIf
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteSelectPos)"
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteResetPos(*table.SQ3_TABLEMAP)
If *table\Table <> 0
*table\RowPos = 0
*table\ColPos = 0
ProcedureReturn #True
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteResetPos)"
EndIf
ProcedureReturn #False
EndProcedure
Procedure.s SQLiteColName(*table.SQ3_TABLEMAP, Col.l)
Protected *value.l
If *table\Table <> 0
If Col > 0 And Col <= *table\Cols
*value.l = PeekL(*table\Table + ((Col - 1) * 4))
If *value
ProcedureReturn PeekS(*value, #PB_Any, SQ3\PeekMode)
EndIf
EndIf
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteColName)"
EndIf
ProcedureReturn ""
EndProcedure
Procedure.s SQLiteValue(*table.SQ3_TABLEMAP)
Protected *value.l
If *table\Table <> 0
If *table\RowPos > 0 And *table\RowPos <= *table\Rows And *table\ColPos > 0 And *table\ColPos <= *table\Cols
*value.l = PeekL(*table\Table + ((*table\ColPos - 1 + (*table\RowPos * *table\Cols)) * 4))
If *value
ProcedureReturn PeekS(*value, #PB_Any, SQ3\PeekMode)
EndIf
EndIf
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteValue)"
EndIf
ProcedureReturn ""
EndProcedure
Procedure.s SQLiteRowValue(*table.SQ3_TABLEMAP, Row.l)
Protected *value.l
If *table\Table <> 0
If Row > 0 And Row <= *table\Rows And *table\Cols > 0 And *table\Cols <= *table\Cols
*value = PeekL(*table\Table + ((*table\Cols - 1 + (Row * *table\Cols)) * 4))
If *value
ProcedureReturn PeekS(*value, #PB_Any, SQ3\PeekMode)
EndIf
EndIf
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteRowValue)"
EndIf
ProcedureReturn ""
EndProcedure
Procedure.s SQLiteColValue(*table.SQ3_TABLEMAP, Col.l)
Protected *value.l
If *table\Table <> 0
If *table\RowPos > 0 And *table\RowPos <= *table\Rows And Col > 0 And Col <= *table\Cols
*value = PeekL(*table\Table + ((Col - 1 + (*table\RowPos * *table\Cols)) * 4))
If *value
ProcedureReturn PeekS(*value, #PB_Any, SQ3\PeekMode)
EndIf
EndIf
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteColValue)"
EndIf
ProcedureReturn ""
EndProcedure
Procedure.s SQLiteSelectValue(*table.SQ3_TABLEMAP, Row.l, Col.l)
Protected *value.l
If *table\Table <> 0
If Row > 0 And Row <= *table\Rows And Col > 0 And Col <= *table\Cols
*value.l = PeekL(*table\Table + ((Col - 1 + (Row * *table\Cols)) * 4))
If *value
ProcedureReturn PeekS(*value, #PB_Any, SQ3\PeekMode)
EndIf
EndIf
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteSelectValue)"
EndIf
ProcedureReturn ""
EndProcedure
Procedure.l SQLiteRows(*table.SQ3_TABLEMAP)
If *table\Table <> 0
ProcedureReturn *table\Rows
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteRows)"
EndIf
ProcedureReturn #False
EndProcedure
Procedure.l SQLiteCols(*table.SQ3_TABLEMAP)
If *table\Table <> 0
ProcedureReturn *table\Cols
Else
SQ3\last_message = "Invalid table handle"
Debug "SQLite: '"+SQ3\last_message+"' (SQLiteCols)"
EndIf
ProcedureReturn #False
EndProcedure