Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/17/2024 in all areas

  1. jpm

    SQLite Foreign Keys

    Thanks @Andreik I will add that to the SQLite.au3 I Will not check for library version as the Version 3.6.19 was introduced before the first SQLite.au3
    1 point
  2. Andreik

    SQLite Foreign Keys

    Following your suggestions. Added two examples also: First example is what might be default behavior of _SQLite_Open() where foreign keys are disabled by default. Second example is how the new parameter $bFKEnable would work to enable foreign keys when the database is opened. _SQLite_ForeignKeys() with $bFKEnable = Default returns current foreign_keys setting or if $bFKEnable is provided as a boolean value will enable/disable foreign keys support. Success: returns current foreign_keys setting as boolean value (enabled/disabled) Failure: returns a value that can be compared against $SQLITE_* constants @error = 1 - Cannot retrieve current foreign_keys setting (@extended contains the error code returned by _SQLite_QuerySingleRow). @error = 2 - Cannot set foreign_keys setting (@extended contains the error code returned by _SQLite_Exec). #include <SQLite.au3> _SQLite_Startup() ;~ ################################################################# ;~ # Example #1 # ;~ ################################################################# ConsoleWrite('Running example #1' & @CRLF) $hDB = _SQLite_Open2() ; Current value ConsoleWrite('Current foreign_keys setting: ' & _SQLite_ForeignKeys() & @CRLF) ; Enable foreign keys _SQLite_ForeignKeys($hDB, True) ConsoleWrite('Current foreign_keys setting: ' & _SQLite_ForeignKeys() & @CRLF) ; Disable foreign keys _SQLite_ForeignKeys($hDB, False) ConsoleWrite('Current foreign_keys setting: ' & _SQLite_ForeignKeys() & @CRLF) _SQLite_Close($hDB) ;~ ################################################################# ;~ ################################################################# ;~ # Example #2 # ;~ ################################################################# ConsoleWrite('Running example #2' & @CRLF) $hDB = _SQLite_Open2(Default, Default, Default, True) ; Current value ConsoleWrite('Current foreign_keys setting: ' & _SQLite_ForeignKeys() & @CRLF) _SQLite_Close($hDB) ;~ ################################################################# _SQLite_Shutdown() Func _SQLite_ForeignKeys($hDB = Default, $bFKEnable = Default) If $hDB = Default Then $hDB = -1 ; $bFKEnable = Default - Return current PRAGMA foreign_keys setting If $bFKEnable = Default Then Local $aRow Local $iQueryRet = _SQLite_QuerySingleRow($hDB, 'PRAGMA foreign_keys;', $aRow) If @error Then Return SetError(1, @error, $iQueryRet) Return SetError(0, 0, $aRow[0] = 1 ? True : False) EndIf ; $bFKEnable = True - Enable foreign keys ; $bFKEnable = False - Disable foreign keys Local $iExecRet = _SQLite_Exec($hDB, 'PRAGMA foreign_keys = ' & ($bFKEnable ? 'ON' : 'OFF') & ';') If $iExecRet = $SQLITE_OK Then Return SetError(0, 0, $bFKEnable ? True : False) Else Return SetError(2, @error, $iExecRet) EndIf EndFunc ;==>_SQLite_ForeignKeys Func _SQLite_Open2($sDatabase_Filename = Default, $iAccessMode = Default, $iEncoding = Default, $bFKEnable = Default) If Not $__g_hDll_SQLite Then Return SetError(3, $SQLITE_MISUSE, 0) If $sDatabase_Filename = Default Or Not IsString($sDatabase_Filename) Then $sDatabase_Filename = ":memory:" Local $tFilename = __SQLite_StringToUtf8Struct($sDatabase_Filename) If @error Then Return SetError(2, @error, 0) If $iAccessMode = Default Then $iAccessMode = BitOR($SQLITE_OPEN_READWRITE, $SQLITE_OPEN_CREATE) Local $bOldBase = FileExists($sDatabase_Filename) ; encoding cannot be changed if base already exists If $iEncoding = Default Then $iEncoding = $SQLITE_ENCODING_UTF8 EndIf Local $avRval = DllCall($__g_hDll_SQLite, "int:cdecl", "sqlite3_open_v2", "struct*", $tFilename, _ ; UTF-8 Database filename "ptr*", 0, _ ; OUT: SQLite db handle "int", $iAccessMode, _ ; database access mode "ptr", 0) If @error Then Return SetError(1, @error, 0) ; DllCall error If $avRval[0] <> $SQLITE_OK Then __SQLite_ReportError($avRval[2], "_SQLite_Open") _SQLite_Close($avRval[2]) Return SetError(-1, $avRval[0], 0) EndIf $__g_hDB_SQLite = $avRval[2] __SQLite_hAdd($__g_ahDBs_SQLite, $avRval[2]) If Not $bOldBase Then Local $aEncoding[3] = ["8", "16", "16be"] _SQLite_Exec($avRval[2], 'PRAGMA encoding="UTF-' & $aEncoding[$iEncoding] & '";') EndIf ; Foreign keys support ; ##################################### If $bFKEnable = Default Then $bFKEnable = False If $bFKEnable Then _SQLite_ForeignKeys($avRval[2], $bFKEnable) If @error Then Local $iError = @error _SQLite_Close($avRval[2]) Return SetError(4, $iError, 0) EndIf EndIf ; ##################################### Return SetExtended($avRval[0], $avRval[2]) EndFunc ;==>_SQLite_Open One more example with foreign keys enabled. #include <SQLite.au3> _SQLite_Startup() $hDB = _SQLite_Open2(Default, Default, Default, True) _SQLite_Exec($hDB, 'CREATE TABLE Authors(idAuthor INTEGER, AuthorName VARCHAR(64), PRIMARY KEY("idAuthor" AUTOINCREMENT));') _SQLite_Exec($hDB, 'CREATE TABLE Books(idBook INTEGER, idAuthor INTEGER , BookName VARCHAR(64), PRIMARY KEY("idBook" AUTOINCREMENT), FOREIGN KEY("idAuthor") REFERENCES Authors("idAuthor"));') _SQLite_Exec($hDB, 'INSERT INTO Authors(AuthorName) VALUES("Arthur Conan Doyle");') $idAuthor = _SQLite_LastInsertRowID($hDB) ; This should work _SQLite_Exec($hDB, 'INSERT INTO Books(idAuthor, BookName) VALUES(' & $idAuthor & ', "The Lost World");') ; This should fail with message: FOREIGN KEY constraint failed $idAuthor += 1 _SQLite_Exec($hDB, 'INSERT INTO Books(idAuthor, BookName) VALUES(' & $idAuthor & ', "The Final Problem");') Local $aResult, $iRows, $iCols _SQLite_GetTable2D($hDB, 'SELECT * FROM Books;', $aResult, $iRows, $iCols) _SQLite_Display2DResult($aResult) _SQLite_Close($hDB) _SQLite_Shutdown() Func _SQLite_ForeignKeys($hDB = Default, $bFKEnable = Default) If $hDB = Default Then $hDB = -1 ; $bFKEnable = Default - Return current PRAGMA foreign_keys setting If $bFKEnable = Default Then Local $aRow Local $iQueryRet = _SQLite_QuerySingleRow($hDB, 'PRAGMA foreign_keys;', $aRow) If @error Then Return SetError(1, @error, $iQueryRet) Return SetError(0, 0, $aRow[0] = 1 ? True : False) EndIf ; $bFKEnable = True - Enable foreign keys ; $bFKEnable = False - Disable foreign keys Local $iExecRet = _SQLite_Exec($hDB, 'PRAGMA foreign_keys = ' & ($bFKEnable ? 'ON' : 'OFF') & ';') If $iExecRet = $SQLITE_OK Then Return SetError(0, 0, $bFKEnable ? True : False) Else Return SetError(2, @error, $iExecRet) EndIf EndFunc ;==>_SQLite_ForeignKeys Func _SQLite_Open2($sDatabase_Filename = Default, $iAccessMode = Default, $iEncoding = Default, $bFKEnable = Default) If Not $__g_hDll_SQLite Then Return SetError(3, $SQLITE_MISUSE, 0) If $sDatabase_Filename = Default Or Not IsString($sDatabase_Filename) Then $sDatabase_Filename = ":memory:" Local $tFilename = __SQLite_StringToUtf8Struct($sDatabase_Filename) If @error Then Return SetError(2, @error, 0) If $iAccessMode = Default Then $iAccessMode = BitOR($SQLITE_OPEN_READWRITE, $SQLITE_OPEN_CREATE) Local $bOldBase = FileExists($sDatabase_Filename) ; encoding cannot be changed if base already exists If $iEncoding = Default Then $iEncoding = $SQLITE_ENCODING_UTF8 EndIf Local $avRval = DllCall($__g_hDll_SQLite, "int:cdecl", "sqlite3_open_v2", "struct*", $tFilename, _ ; UTF-8 Database filename "ptr*", 0, _ ; OUT: SQLite db handle "int", $iAccessMode, _ ; database access mode "ptr", 0) If @error Then Return SetError(1, @error, 0) ; DllCall error If $avRval[0] <> $SQLITE_OK Then __SQLite_ReportError($avRval[2], "_SQLite_Open") _SQLite_Close($avRval[2]) Return SetError(-1, $avRval[0], 0) EndIf $__g_hDB_SQLite = $avRval[2] __SQLite_hAdd($__g_ahDBs_SQLite, $avRval[2]) If Not $bOldBase Then Local $aEncoding[3] = ["8", "16", "16be"] _SQLite_Exec($avRval[2], 'PRAGMA encoding="UTF-' & $aEncoding[$iEncoding] & '";') EndIf ; Foreign keys support ; ##################################### If $bFKEnable = Default Then $bFKEnable = False If $bFKEnable Then _SQLite_ForeignKeys($avRval[2], $bFKEnable) If @error Then Local $iError = @error _SQLite_Close($avRval[2]) Return SetError(4, $iError, 0) EndIf EndIf ; ##################################### Return SetExtended($avRval[0], $avRval[2]) EndFunc ;==>_SQLite_Open
    1 point
  3. argumentum

    SQLite Foreign Keys

    Or do both. Add the default as false, as to not brake prior code and have the new function too. Tho I would set the default as Default ( in _SQLite_ForeignKey() ), and if is Default, return the current pragma (on/off) setting. Also error check for versions of SQLite not supporting the feature(s). Also, returning -1 instead of Null. Don't remember seeing any other function return null in case of error. To keep it as AutoIt ( users ) friendly as possible. Edit: _SQLite_ForeignKey($hDB = -1, $bFKEnable = Default) would be a better name, and instead of repeating the code in _SQLite_Open(), just add _SQLite_ForeignKey() in that line.
    1 point
  4. @Homeseer666 Just remove the $j loop if you only care with one column, hardcode 0 in place of $j (save you a bit of time) Moreover, you could put all the things you want to FileWrite into a single statement...
    1 point
×
×
  • Create New...