Page 1 of 1

:memory:-Database-Dump (fast and easy)

Posted: Thu Oct 13, 2011 9:01 am
by Kiffi
Hello,

here is a code-snippet to dump a SQLite-:memory:-Database to disk:

Code: Select all

EnableExplicit

ImportC "sqlite3.lib"
  sqlite3_backup_init(pDest, zDestName.p-utf8, pSource, zSourceName.p-utf8) 
  sqlite3_backup_step(sqlite3_backup, nPage)
  sqlite3_backup_finish(sqlite3_backup)
  sqlite3_errcode(db)
EndImport

UseSQLiteDatabase()

Define DbMem
Define DbFile
Define Counter
Define FF
Define Backup
Define RC

; Create Sample-:memory:-Database:

DbMem = OpenDatabase(#PB_Any, ":memory:", "", "", #PB_Database_SQLite)

If DbMem
  
  ; insert test-data
  DatabaseUpdate(DbMem, "Create Table TestTable (Field1, Field2, Field3)")
  For Counter = 0 To 9999
    DatabaseUpdate(DbMem, "Insert Into TestTable (Field1, Field2, Field3) Values (" + Str(Counter) + ", " + Str(Counter) + ", " + Str(Counter) + ")")
  Next
  
  ; Create File-Database
  
  FF = CreateFile(#PB_Any, GetTemporaryDirectory() + "temp.db")
  
  If FF
  
    CloseFile(FF)
    
    DbFile = OpenDatabase(#PB_Any, GetTemporaryDirectory() + "temp.db", "", "", #PB_Database_SQLite)
    
    If DbFile
      
      ; Initialize Backup:
      
      BackUp = sqlite3_backup_init(DatabaseID(DbFile), "main", DatabaseID(DbMem), "main") 
      
      If BackUp
        
        ; Dump Data from :memory:-DB to File-DB
        
        sqlite3_backup_step  (Backup, -1)
        sqlite3_backup_finish(Backup)
        
      EndIf
      
      Debug sqlite3_errcode(DatabaseID(DbFile)) ; ErrorCodes: see below
      
      CloseDatabase(DbFile)
      
      ; RunProgram(GetTemporaryDirectory() + "temp.db") ; Open File-DB for checking purposes
      
    EndIf
    
  EndIf
  
EndIf


; #define SQLITE_OK           0   /* Successful result */
; /* beginning-of-error-codes */
; #define SQLITE_ERROR        1   /* SQL error Or missing database */
; #define SQLITE_INTERNAL     2   /* 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   /* Unknown opcode in sqlite3_file_control() */
; #define SQLITE_FULL        13   /* Insertion failed because database is full */
; #define SQLITE_CANTOPEN    14   /* Unable To open the database file */
; #define SQLITE_PROTOCOL    15   /* 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 */
Greetings ... Kiffi

Re: :memory:-Database-Dump (fast and easy)

Posted: Fri Oct 14, 2011 8:33 am
by srod
Could be useful. Thanks Kiffi. :)

Re: :memory:-Database-Dump (fast and easy)

Posted: Sat Oct 15, 2011 7:25 pm
by Zach
Now all you have to do is write a full wrapper for those of us too lazy to do it ourselves :mrgreen:

This is neat. I've wanted to play with in-memory DB's but never had a easy way to tackle the problem of saving / loading it back

Re: :memory:-Database-Dump (fast and easy)

Posted: Wed Nov 30, 2011 6:17 pm
by srod
Kiffi, will this run on Mac OSX and Linux?

I ask because I am not sure whether there is a SQLite3.lib library file on these systems?

Re: :memory:-Database-Dump (fast and easy)

Posted: Wed Nov 30, 2011 6:35 pm
by freak
Simply ImportC "" should do the trick on all OS. The library will be linked anyway as soon as you use UseSQLiteDatabase().

Re: :memory:-Database-Dump (fast and easy)

Posted: Wed Nov 30, 2011 6:45 pm
by srod
freak wrote:Simply ImportC "" should do the trick on all OS. The library will be linked anyway as soon as you use UseSQLiteDatabase().
Confirmed, works great on Mac OSX. Thanks Freak.

@Kiffi : you should change the sqlite3_backup_init() import to use p-Utf8 pseudotypes in order for the code to run if the Unicode switch is set. :)

Re: :memory:-Database-Dump (fast and easy)

Posted: Wed Nov 30, 2011 7:22 pm
by srod
Here is a version which allows you to backup any SQLite database to any other SQLite database. The 'source' and/or 'destination' databases can be memory based etc. or both can be disc-based.

Pass any 2 valid database# to the function. Note that any existing data in the destination database will be deleted.

Code: Select all

UseSQLiteDatabase()

ImportC ""
  sqlite3_backup_init(pDest, zDestName.p-utf8, pSource, zSourceName.p-utf8) 
  sqlite3_backup_step(sqlite3_backup, nPage)
  sqlite3_backup_finish(sqlite3_backup)
EndImport


;The following backs up one SQlite database to a second SQLite database. Can be used to dump a memory based SQLite database to disc
;or can dump a disc-based SQLite database to a memory one etc.
;Any existing data in the destination database will be deleted.
;Returns #True if successful.
Procedure.i SQLite_BackupSqliteDatabase(sourceDB, destinationDB)
  Protected result, backUp
  If IsDatabase(sourceDB) And IsDatabase(destinationDB)
    backUp = sqlite3_backup_init(DatabaseID(destinationDB), "main", DatabaseID(sourceDB), "main") 
    If backUp
      sqlite3_backup_step(backUp, -1)
      If sqlite3_backup_finish(backUp) = 0 ;#SQLITE_OK
        result = #True    
      EndIf
    EndIf
  EndIf
  ProcedureReturn result
EndProcedure

Thanks Kiffi. This is turning out to be very useful.

Re: :memory:-Database-Dump (fast and easy)

Posted: Wed Nov 30, 2011 8:52 pm
by Kiffi
You're welcome, srod. Thanks for your improvements! Image

Greetings ... Kiffi

Re: :memory:-Database-Dump (fast and easy)

Posted: Thu Nov 05, 2015 10:11 am
by HanPBF
There are two different ImportC in above source codes.

one with

Code: Select all

sqlite3_backup_init(pDest, zDestName.s, pSource, zSourceName.s) 
and one with

Code: Select all

sqlite3_backup_init(pDest, zDestName.p-utf8, pSource, zSourceName.p-utf8)
The first one gives an error
"unknown database m"
maybe due to the fact that string is cut? Or unicode vs. ASCII?

2nd with .p-utf8 works


Thanks a lot for the backup example anyway!!!