SQLite3 BaseFunction-Include for Win + Lin + Unicode

Share your advanced PureBasic knowledge/code with the community.
mskuma
Enthusiast
Enthusiast
Posts: 573
Joined: Sat Dec 03, 2005 1:31 am
Location: Australia

Post by mskuma »

I think I can answer my own question.. after double-checking everything with a better sqlite admin tool, all looks good after all.. using your sample program & latest include ('compile for unicode' & UTF8 source) I could add unicode chars & retrieve them from the db. Thanks alot ts-soft, it's great. There's a lesson.. don't trust 3rd party tools for proper display of unicode text (or proper unicode editing capbility either).
mskuma
Enthusiast
Enthusiast
Posts: 573
Joined: Sat Dec 03, 2005 1:31 am
Location: Australia

Post by mskuma »

Can someone explain the merit of using SQliteGetTable/SQLiteNextRow vs SQLitePrepare/SQLiteStep? That is, I guess the following 2 codes are basically equivalent, but in which situation would you prefer one style instead of the other?

Code: Select all

SQliteGetTable(hDB, "SELECT * FROM test", Table) 
If Table

  Debug " -- data --"
  While SQLiteNextRow(Table) 
    i + 1 : Debug "_row " + Str(i) + ":" 
    While SQLiteNextCol(Table) 
      Debug SQLiteValue(Table) 
    Wend 
  Wend
  ; 
  ;;;;;;;;;;;;;;;;;;;;;;; 
  SQliteFreeTable(Table) 
EndIf 

Code: Select all

lStatement = SQLitePrepare(hDB, "SELECT * FROM test")

While SQLiteStep(lStatement) <> #False

  Debug SQLiteColumnText(lStatement, 0) + " " + SQLiteColumnText(lStatement, 1) + " " + SQLiteColumnText(lStatement, 2)
  
Wend

SQLiteFinalize(lStatement)
I gather SQLiteFinalize is required also.. is that so? Thanks alot.

BTW thanks again ts-soft for providing this (and thanks to MLK & Kiffi too I think).. it's very nice.
gekkonier
User
User
Posts: 78
Joined: Mon Apr 23, 2007 9:42 am

Post by gekkonier »

Thank you very much for this charm!
With the provided examples it is easy to understand too!
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

Updated Version using Staticlib from PB4.2x

Code: Select all

; 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
; new Version For PB 4.20 + using static lib from pb

; ascii compatibility-functions 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

UseSQLiteDatabase()

ImportC ""
  sqlite3_close (hDB.l)
  sqlite3_errcode (hDB.l)
  sqlite3_errmsg (hDB.l)
  sqlite3_errmsg16 (hDB.l)
  sqlite3_exec (hDB.l, Statement.p-utf8, cb.l = 0, cbdata.l = 0, errmsg.l = 0)
  sqlite3_free_table (*table)
  sqlite3_get_table (hDB.l, Statement.p-utf8, *table, nRow.l, nColumn.l, errmsg.l = 0)
  sqlite3_libversion ()
  sqlite3_open (filename.s, *hDB)
  sqlite3_open16 (filename.s, *hDB)
  sqlite3_last_insert_rowid (hDB.l)
  sqlite3_prepare (hDB.l, Statement.p-utf8, nBytes.l, *hResult, *pzTail = 0)
  sqlite3_prepare16 (hDB.l, Statement.p-unicode, nBytes.l, *hResult, *pzTail = 0)
  sqlite3_finalize (lStatement.l)
  sqlite3_reset(lStatement.l)
  sqlite3_step (lStatement.l)
  sqlite3_bind_blob (lStatement.l, lIndex.l, lBinaryBuffer.l, lBinaryBufferLength.l, *void = -1)
  sqlite3_bind_double (lStatement.l, lIndex.l, dValue.d)
  sqlite3_bind_int (lStatement.l, lIndex.l, lValue.l)
  sqlite3_bind_int64 (lStatement.l, lIndex.l, qValue.q)
  sqlite3_bind_text (lStatement, lIndex, lTextBuffer.p-ascii, len.l = -1, type.l = #SQLITE_TRANSIENT)
  sqlite3_bind_text16 (lStatement, lIndex, lTextBuffer.p-unicode, len.l = -1, type.l = #SQLITE_TRANSIENT)
  sqlite3_column (lStatement, lCol.l)
  sqlite3_column_double (lStatement, lCol.l)
  sqlite3_column_quad (lStatement, lCol.l)
  sqlite3_column_blob (lStatement, lCol.l)
  sqlite3_column_bytes (lStatement, lCol.l)
  sqlite3_column_bytes16 (lStatement, lCol.l)
  sqlite3_column_int (lStatement, lCol.l)
  sqlite3_column_int64 (lStatement, lCol.l)
  sqlite3_column_text (lStatement, lCol.l)
  sqlite3_column_text16 (lStatement, lCol.l)
  sqlite3_column_type (lStatement, lCol.l)
EndImport

Structure SQ3_TABLEMAP
  Table.l
  Rows.l
  Cols.l
  RowPos.l
  ColPos.l
EndStructure

Procedure.l SQLiteClose(hDB.l)
  If Not hDB : ProcedureReturn #False : EndIf
  If Not sqlite3_close(hDB)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteOpen(FileName.s)
  Protected hDB.l
  CompilerIf #PB_Compiler_Unicode
  If Not sqlite3_open16(FileName, @hDB)
    ProcedureReturn hDB
  EndIf
  CompilerElse
  If Not sqlite3_open(FileName, @hDB)
    ProcedureReturn hDB
  EndIf
  CompilerEndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteErrorCode(hDB.l)
  If Not hDB : ProcedureReturn -1 : EndIf
  ProcedureReturn sqlite3_errcode(hDB)
EndProcedure

Procedure.s SQLiteErrorMsg(hDB.l)
  If Not hDB : ProcedureReturn "Database handle missing" : EndIf
  CompilerIf #PB_Compiler_Unicode
  ProcedureReturn PeekS(sqlite3_errmsg16(hDB))
  CompilerElse
  ProcedureReturn PeekS(sqlite3_errmsg(hDB))
  CompilerEndIf
EndProcedure


Procedure.s SQLiteLibversion()
  ProcedureReturn PeekS(sqlite3_libversion(), #PB_Any, #PB_Ascii)
EndProcedure

Procedure.l SQLiteExecute(hDB.l, Statement.s, callback.l = 0, cbpara.l = 0)
  If Not hDB : ProcedureReturn #False : EndIf
  If Not sqlite3_exec(hDB, Statement, callback, cbpara)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteLastInsertRowId(hDB.l)
  If Not hDB : ProcedureReturn #False : EndIf
  ProcedureReturn sqlite3_last_insert_rowid(hDB)
EndProcedure

; table-functions
Procedure.l SQliteFreeTable(*table.SQ3_TABLEMAP)
  If *table
    sqlite3_free_table(*table\Table)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteGetTable(hDB.l, Statement.s, *table.SQ3_TABLEMAP)
  Protected nRow.l, nColumn.l, lResultPtr.l, result.l
  If Not hDB : ProcedureReturn #False : EndIf
  result = sqlite3_get_table(hDB, Statement, @lResultPtr, @nRow, @nColumn)
  If Not result
    *table\Table = lResultPtr
    *table\Rows = nRow
    *table\Cols = nColumn
    *table\RowPos = 0
    *table\ColPos = 0
    ProcedureReturn *table
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteNextRow(*Table.SQ3_TABLEMAP)
  If *Table
    If *Table\RowPos < *Table\Rows
      *Table\RowPos + 1
      ProcedureReturn #True
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteNextCol(*Table.SQ3_TABLEMAP)
  If *Table
    If *Table\ColPos < *Table\Cols
      *Table\ColPos + 1
      ProcedureReturn #True
    Else
      *Table\ColPos = 0
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteSelectRow(*Table.SQ3_TABLEMAP, Row.l)
  If *Table
    If Row > 0 And Row <= *Table\Rows
      *Table\RowPos = Row
      ProcedureReturn #True
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteSelectCol(*Table.SQ3_TABLEMAP, Col.l)
  If *Table
    If Col > 0 And Col <= *Table\Cols
      *Table\ColPos = Col
      ProcedureReturn #True
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteSelectPos(*Table.SQ3_TABLEMAP, Row.l, Col.l)
  If *Table
    If Row > 0 And Row <= *Table\Rows And Col > 0 And Col <= *Table\Cols
      *Table\RowPos = Row
      *Table\ColPos = Col
      ProcedureReturn #True
    EndIf
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteResetPos(*Table.SQ3_TABLEMAP)
  If *Table
    *Table\RowPos = 0
    *Table\ColPos = 0
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.s SQLiteColName(*Table.SQ3_TABLEMAP, Col.l)
  Protected *val.l
  If *Table
    If Col > 0 And Col <= *Table\Cols
      *val.l = PeekL(*Table\Table + ((Col - 1) * 4))
      If *val
        ProcedureReturn PeekS(*val, #PB_Any, #PB_UTF8)
      EndIf
    EndIf
  EndIf
  ProcedureReturn ""
EndProcedure

Procedure.s SQLiteValue(*Table.SQ3_TABLEMAP)
  Protected *val.l
  If *Table
    If *Table\RowPos > 0 And *Table\RowPos <= *Table\Rows And *Table\ColPos > 0 And *Table\ColPos <= *Table\Cols
      *val.l = PeekL(*Table\Table + ((*Table\ColPos - 1 + (*Table\RowPos * *Table\Cols)) * 4))
      If *val
        ProcedureReturn PeekS(*val, #PB_Any, #PB_UTF8)
      EndIf
    EndIf
  EndIf
  ProcedureReturn ""
EndProcedure

Procedure.s SQLiteRowValue(*Table.SQ3_TABLEMAP, Row.l)
  Protected *val.l
  If *Table
    If Row > 0 And Row <= *Table\Rows And *Table\Cols > 0 And *Table\Cols <= *Table\Cols
      *val.l = PeekL(*Table\Table + ((*Table\Cols - 1 + (Row * *Table\Cols)) * 4))
      If *val
        ProcedureReturn PeekS(*val, #PB_Any, #PB_UTF8)
      EndIf
    EndIf
  EndIf
  ProcedureReturn ""
EndProcedure

Procedure.s SQLiteColValue(*Table.SQ3_TABLEMAP, Col.l)
  Protected *val.l
  If *Table
    If *Table\RowPos > 0 And *Table\RowPos <= *Table\Rows And Col > 0 And Col <= *Table\Cols
      *val.l = PeekL(*Table\Table + ((Col - 1 + (*Table\RowPos * *Table\Cols)) * 4))
      If *val
        ProcedureReturn PeekS(*val, #PB_Any, #PB_UTF8)
      EndIf
    EndIf
  EndIf
  ProcedureReturn ""
EndProcedure

Procedure.s SQLiteSelectValue(*Table.SQ3_TABLEMAP, Row.l, Col.l)
  Protected *val.l
  If *Table
    If Row > 0 And Row <= *Table\Rows And Col > 0 And Col <= *Table\Cols
      *val.l = PeekL(*Table\Table + ((Col - 1 + (Row * *Table\Cols)) * 4))
      If *val
        ProcedureReturn PeekS(*val, #PB_Any, #PB_UTF8)
      EndIf
    EndIf
  EndIf
  ProcedureReturn ""
EndProcedure

Procedure.l SQLiteRows(*Table.SQ3_TABLEMAP)
  If *Table
    ProcedureReturn *Table\Rows
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteCols(*Table.SQ3_TABLEMAP)
  If *Table
    ProcedureReturn *Table\Cols
  EndIf
  ProcedureReturn #False
EndProcedure

; binding-functions
Procedure.l SQLitePrepare(hDB.l, Statement.s); Result is lStatement
  Protected Result.l
  CompilerIf #PB_Compiler_Unicode
  If Not sqlite3_prepare16(hDB, Statement, -1, @Result)
    ProcedureReturn Result
  EndIf
  CompilerElse
  If Not sqlite3_prepare(hDB, Statement, -1, @Result)
    ProcedureReturn Result
  EndIf
  CompilerEndIf
EndProcedure

Procedure.l SQLiteFinalize(lStatement.l)
  If Not sqlite3_finalize(lStatement)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteReset(lStatement.l)
  If Not sqlite3_reset(lStatement)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteStep(lStatement.l)
  If sqlite3_step(lStatement) = #SQLITE3_ROW
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteBindBlob(lStatement.l, lIndex.l, lBuffer.l, lBufferLength.l)
  If Not sqlite3_bind_blob(lStatement, lIndex, lBuffer, lBufferLength)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteBindDouble(lStatement.l, lIndex.l, dValue.d)
  If Not sqlite3_bind_double(lStatement, lIndex, dValue)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteBindLong(lStatement.l, lIndex.l, lValue.l)
  If Not sqlite3_bind_int(lStatement, lIndex, lValue)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteBindQuad(lStatement.l, lIndex.l, qValue.q)
  If Not sqlite3_bind_int64(lStatement, lIndex, qValue)
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteBindText(lStatement.l, lIndex.l, Text.s)
  CompilerIf #PB_Compiler_Unicode
  If Not sqlite3_bind_text16(lStatement, lIndex, Text)
    ProcedureReturn #True
  EndIf
  CompilerElse
  If Not sqlite3_bind_text(lStatement, lIndex, Text)
    ProcedureReturn #True
  EndIf
  CompilerEndIf
  ProcedureReturn #False
EndProcedure

Procedure.l SQLiteColumnBlob(lStatement.l, lColumn.l)
  ProcedureReturn sqlite3_column_blob(lStatement, lColumn)
EndProcedure

Procedure.l SQLiteColumnByte(lStatement.l, lColumn.l)
  CompilerIf #PB_Compiler_Unicode
  ProcedureReturn sqlite3_column_bytes16(lStatement, lColumn)
  CompilerElse
  ProcedureReturn sqlite3_column_bytes(lStatement, lColumn)
  CompilerEndIf
EndProcedure

Procedure.d SQLiteColumnDouble(lStatement.l, lColumn.l)
  ProcedureReturn sqlite3_column_double(lStatement, lColumn)
EndProcedure

Procedure.l SQLiteColumnLong(lStatement.l, lColumn.l)
  ProcedureReturn sqlite3_column_int(lStatement, lColumn)
EndProcedure

Procedure.q SQLiteColumnQuad(lStatement.l, lColumn.l)
  ProcedureReturn sqlite3_column_int64(lStatement, lColumn)
EndProcedure

Procedure.s SQLiteColumnText(lStatement.l, lColumn.l)
  Protected Result.l
  CompilerIf #PB_Compiler_Unicode
  Result = sqlite3_column_text16(lStatement, lColumn)
  If Result
    ProcedureReturn PeekS(Result)
  EndIf
  CompilerElse
  Result = sqlite3_column_text(lStatement, lColumn)
  If Result
    ProcedureReturn PeekS(Result)
  EndIf
  CompilerEndIf
EndProcedure

Procedure.l SQLiteColumnType(lStatement.l, lColumn.l)
  ProcedureReturn sqlite3_column_type(lStatement, lColumn)
EndProcedure
// edit
bugfix for SQLiteBindText (ASCII and Unicode)

// edit2
added SQLiteReset(lStatement.l)

// edit3
removed useless macros
added check for nullpointer in SQLiteColumnText()

greetings
Thomas
Last edited by ts-soft on Tue Jun 10, 2008 1:37 pm, edited 2 times in total.
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

Update:
SQLiteBindText fixed for static lib
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

mskuma wrote:Can someone explain the merit of using SQliteGetTable/SQLiteNextRow vs SQLitePrepare/SQLiteStep? That is, I guess the following 2 codes are basically equivalent, but in which situation would you prefer one style instead of the other?

Code: Select all

SQliteGetTable(hDB, "SELECT * FROM test", Table) 
If Table

  Debug " -- data --"
  While SQLiteNextRow(Table) 
    i + 1 : Debug "_row " + Str(i) + ":" 
    While SQLiteNextCol(Table) 
      Debug SQLiteValue(Table) 
    Wend 
  Wend
  ; 
  ;;;;;;;;;;;;;;;;;;;;;;; 
  SQliteFreeTable(Table) 
EndIf 

Code: Select all

lStatement = SQLitePrepare(hDB, "SELECT * FROM test")

While SQLiteStep(lStatement) <> #False

  Debug SQLiteColumnText(lStatement, 0) + " " + SQLiteColumnText(lStatement, 1) + " " + SQLiteColumnText(lStatement, 2)
  
Wend

SQLiteFinalize(lStatement)
I gather SQLiteFinalize is required also.. is that so? Thanks alot.

BTW thanks again ts-soft for providing this (and thanks to MLK & Kiffi too I think).. it's very nice.
Gettable will put the whole recordset (not the whole table if a where statement is used) into memory which could be very large. It's a wrapper function designed to make things easy but I would avoid it if possible unless you are just using sqlite for a settings file or something else small.

Prep/step/finalise is the way to go to select records out (or use the callback) and exec is run statements that don't return a recordset.

I don't know of any benfit of using GetTable() other than it being easier to understand if you are new to sqlite.

According to SQLite.org GetTable is flaged as "Convenience Routines For Running Queries"
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
nicolaus
Enthusiast
Enthusiast
Posts: 456
Joined: Tue Aug 05, 2003 11:30 pm
Contact:

Post by nicolaus »

@ts-soft

How i can insert a value and blob at the same time into a db?
User avatar
Kiffi
Addict
Addict
Posts: 1485
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Post by Kiffi »

nicolaus wrote:How i can insert a value and blob at the same time into a db?

Code: Select all

lStatement = SQLitePrepare(YourDb, YourBindingQuery)
If lStatement
  SQLiteBindText(lStatement, 0, YourText) ; Inserts a text into the Field 0
  SQLiteBindBlob(lStatement, 1, YourBlob) ; Inserts a blob into the Field 1
  SQLiteStep(lStatement)
EndIf
(untested)

Greetings ... Kiffi
Hygge
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Trying to follow the code:)

Post by Fangbeast »

I want to get the total count of records in a table and not quite sure how/why your examples work.

In the below code, does "SQLiteColumnText(lStatement, 0)" hold the result of that count? 0 = column 0? (and the only returned column for that query)

Code: Select all

lStatement = SQLitePrepare(dbHandle, "SELECT COUNT(record) AS totalrecs FROM addresses")
While SQLiteStep(lStatement) <> #False
  Debug SQLiteColumnText(lStatement, 0)
 Wend
SQLiteFinalize(lStatement)
And if I did the below; assuming that I have a table with Firstname, MiddleName and Lastname; a known number of columns; this is the equivalent of WhileNextDatabaseRow?

This way of SQLiting is very unfamiliar territory to me.

Code: Select all

lStatement = SQLitePrepare(Program\dbHandle, "SELECT * FROM addresses")

While SQLiteStep(lStatement) <> #False

  Debug SQLiteColumnText(lStatement, 0) ; Column 0? (Firstname)
  Debug SQLiteColumnText(lStatement, 1) ; Column 1? (Middlename)
  Debug SQLiteColumnText(lStatement, 2) ; Column 2? (Lasttname)
 
Wend

SQLiteFinalize(lStatement)
**EDIT** I think I may be getting the hang of it:)
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Is there a way to generically escape illegal characters? At the moment, I only handle single quote marks and it is a bit messy.

(Haven't even thought of unicode or high ascii chars yet (scared look))
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

And another problem

Post by Fangbeast »

Lack of understanding on my part no doubt. If I do this, I get all my data back, no problem.

Code: Select all

Table.SQ3_TABLEMAP

SQliteGetTable(hDB, "SELECT * FROM addresses", Table)

If Table
  While SQLiteNextRow(Table)
    While SQLiteNextCol(Table)
      Ass + SQLiteValue(Table) + " "
    Wend
    Debug Ass
    Ass = ""
  Wend
EndIf
If I do this:

Code: Select all

lStatement = SQLitePrepare(hDB, "SELECT * FROM addresses")
  While SQLiteStep(lStatement) <> #False
    Debug SQLiteColumnText(lStatement,  0)
;     Debug SQLiteColumnText(lStatement,  1)
;     Debug SQLiteColumnText(lStatement,  2)
;     Debug SQLiteColumnText(lStatement,  3)
;     Debug SQLiteColumnText(lStatement,  4)
;     Debug SQLiteColumnText(lStatement,  5)
;     Debug SQLiteColumnText(lStatement,  6)
;     Debug SQLiteColumnText(lStatement, 27)
  Wend
SQLiteFinalize(lStatement)
I get a Procedure.s "ERROR, specified address is null" error from:

Code: Select all

SQLiteColumnText(lStatement.l, lColumn.l)
  CompilerIf #PB_Compiler_Unicode
    If SQ3\column_text16
      ProcedureReturn PeekS(SQ3\column_text16(lStatement, lColumn))
    EndIf
  CompilerElse
    If SQ3\column_text
      ProcedureReturn PeekS(SQ3\column_text(lStatement, lColumn))
    EndIf
  CompilerEndIf
  ProcedureReturn ""
EndProcedure
Aren't the two routines supposed to do the same thing? (From my limited understanding)
User avatar
pdwyer
Addict
Addict
Posts: 2813
Joined: Tue May 08, 2007 1:27 pm
Location: Chiba, Japan

Post by pdwyer »

(Once again, not sure about PB & SQLite)

Generally SQLite lets you get creative (free) with data types, you can call a string column data the same way you'd get data out of a blob and just receive a pointer to a chunk of memory and from there do with it as you like

On sqlite.org there is also a list what conversions take place behind the scenes between utf8 and utf16 etc depending on how you interact with the library, there are even gotchas listed as the order of doing things may effect conversions.

Perhaps its not relevent to your question though... not sure
Paul Dwyer

“In nature, it’s not the strongest nor the most intelligent who survives. It’s the most adaptable to change” - Charles Darwin
“If you can't explain it to a six-year old you really don't understand it yourself.” - Albert Einstein
User avatar
Kiffi
Addict
Addict
Posts: 1485
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: And another problem

Post by Kiffi »

Fangbeast wrote:I get a Procedure.s "ERROR, specified address is null" error
using PB4.2 B6, the newest include [1], your snipppet and my database
everythings works fine. No Errors here.

Greetings ... Kiffi

[1]: http://www.purebasic.fr/english/viewtop ... 853#240853
Hygge
User avatar
Fangbeast
PureBasic Protozoa
PureBasic Protozoa
Posts: 4789
Joined: Fri Apr 25, 2003 3:08 pm
Location: Not Sydney!!! (Bad water, no goats)

Post by Fangbeast »

Hi Kiffi, thanks for the reply. I'm using an older include that works with 4.1x as I have to stay on that compiler for lib compatabily reasons with my programs.

I will keep bashing the code:)
User avatar
Kiffi
Addict
Addict
Posts: 1485
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Post by Kiffi »

Fangbeast wrote:I'm using an older include
this one: http://www.purebasic.fr/english/viewtop ... 667#194667?

Testing this include with your snippet and PB 4.1 also
works fine and no error occurred ;-)

Greetings ... Kiffi
Hygge
Post Reply