SQLite3 BaseFunction-Include - Invalid Memory

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Thorsten1867
Beiträge: 1360
Registriert: 04.02.2005 15:40
Computerausstattung: [Windows 10 x64] [PB V5.7x]
Wohnort: Kaufbeuren
Kontaktdaten:

SQLite3 BaseFunction-Include - Invalid Memory

Beitrag von Thorsten1867 »

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

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
Download of PureBasic - Module
Download of PureBasic - Programmes

[Windows 11 x64] [PB V6]

Bild
Benutzeravatar
michel51
Beiträge: 84
Registriert: 01.11.2005 20:00
Wohnort: Dornhan-Weiden

Beitrag von michel51 »

Ich bekomme hiermit einen >> Linker-Error <<

Code: Alles auswählen

EnableExplicit
XIncludeFile "SQLite3_Include_Th1867.pbi"

Define.l hDB, r, i, sqlhdl
Define.SQ3_TABLEMAP Table

If SQLiteInit() = 0
  MessageRequester("Error", "Couldn't init SQLite3 lib") : End
EndIf
;
; Debug SQLiteLibVersion()      ; 3.1.3
;
hDB = SQLiteOpen("testDB.db")
If Not hDB
  MessageRequester("Error", SQliteErrorMsg(hDB)) : End
EndIf
; 
If SQliteExecute(hDB, "CREATE TABLE testtable (spalte1, spalte2, spalte3)") = #FALSE
  Debug SQliteErrorMsg(hDB)
; Else
;   For r = 1 To 5
;     If SQliteExecute(hDB, "INSERT INTO testtable (spalte1, spalte2, spalte3) VALUES ('r" + Str(r) + "c1', 'r" + Str(r) + "c2', 'r" + Str(r) + "c3')") = #FALSE
;       Debug SQliteErrorMsg(hDB)
;     EndIf
;   Next
EndIf

SQLiteClose(hDB)
SQLiteEnd()
Das Include ist dein (geändertes).
Habe ich was übersehen?
michel51

Mac OS X Snow Leopard (10.6.8 ) Intel
PureBasic V 5.11(X64), V 5.21(x64)

Zum Lernen ist niemand zu alt.
Benutzeravatar
Kiffi
Beiträge: 10714
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Beitrag von Kiffi »

michel51 hat geschrieben:Ich bekomme hiermit einen >> Linker-Error <<
läuft hier (PB 4.1) ohne Probleme.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
Thorsten1867
Beiträge: 1360
Registriert: 04.02.2005 15:40
Computerausstattung: [Windows 10 x64] [PB V5.7x]
Wohnort: Kaufbeuren
Kontaktdaten:

Beitrag von Thorsten1867 »

Ich habe es nur mit Windows getestet. Dort scheint es zu funktionieren.
Download of PureBasic - Module
Download of PureBasic - Programmes

[Windows 11 x64] [PB V6]

Bild
Antworten