Jerry Hayes wrote: >What?s the best way to create my own custom pragmas? > >Can I hook into them with the authorizer, (will they even hit the authorizer >if they?re non-standard)? Yes, you can use the authorizer callback to intercept custom pragmas. Please see the attached demo for an example. Ralf
{ DISQLite3 project to monitor the authorizer working. Visit the DISQLite3 Internet site for latest information and updates: http://www.yunqa.de/delphi/ Copyright (c) 2005-2008 Ralf Junker, The Delphi Inspiration <delphi@xxxxxxxx> ------------------------------------------------------------------------------ } program DISQLite3_Authorizer; {$APPTYPE CONSOLE} {$I DI.inc} {$I DISQLite3.inc} {$IFDEF DISQLite3_Personal} !!! This project requires functionality not available with DISQLite3 personal !!! !!! Download DISQLite3 Professional from http://www.yunqa.de !!! {$ENDIF DISQLite3_Personal} uses {$IFDEF FastMM}FastMM4, {$ENDIF}SysUtils, DISQLite3Api; type TAuthorizerText = record a2: Integer; t2: PAnsiChar; t3: PAnsiChar; t4: PAnsiChar; end; const a: array[0..30] of TAuthorizerText = ( (a2: SQLITE_CREATE_INDEX; t2: 'SQLITE_CREATE_INDEX'; t3: 'Index Name'; t4: 'Table Name'), (a2: SQLITE_CREATE_TABLE; t2: 'SQLITE_CREATE_TABLE'; t3: 'Table Name'), (a2: SQLITE_CREATE_TEMP_INDEX; t2: 'SQLITE_CREATE_TEMP_INDEX'; t3: 'Index Name'; t4: 'Table Name'), (a2: SQLITE_CREATE_TEMP_TABLE; t2: 'SQLITE_CREATE_TEMP_TABLE'; t3: 'Table Name'), (a2: SQLITE_CREATE_TEMP_TRIGGER; t2: 'SQLITE_CREATE_TEMP_TRIGGER'; t3: 'Trigger Name'; t4: 'Table Name'), (a2: SQLITE_CREATE_TEMP_VIEW; t2: 'SQLITE_CREATE_TEMP_VIEW'; t3: 'View Name'), (a2: SQLITE_CREATE_TRIGGER; t2: 'SQLITE_CREATE_TRIGGER'; t3: 'Trigger Name'; t4: 'Table Name'), (a2: SQLITE_CREATE_VIEW; t2: 'SQLITE_CREATE_VIEW'; t3: 'View Name'), (a2: SQLITE_DELETE; t2: 'SQLITE_DELETE'; t3: 'Table Name'), (a2: SQLITE_DROP_INDEX; t2: 'SQLITE_DROP_INDEX'; t3: 'Index Name'; t4: 'Table Name'), (a2: SQLITE_DROP_TABLE; t2: 'SQLITE_DROP_TABLE'; t3: 'Table Name'), (a2: SQLITE_DROP_TEMP_INDEX; t2: 'SQLITE_DROP_TEMP_INDEX'; t3: 'Index Name'; t4: 'Table Name'), (a2: SQLITE_DROP_TEMP_TABLE; t2: 'SQLITE_DROP_TEMP_TABLE'; t3: 'Table Name'), (a2: SQLITE_DROP_TEMP_TRIGGER; t2: 'SQLITE_DROP_TEMP_TRIGGER'; t3: 'Trigger Name'; t4: 'Table Name'), (a2: SQLITE_DROP_TEMP_VIEW; t2: 'SQLITE_DROP_TEMP_VIEW'; t3: 'View Name'), (a2: SQLITE_DROP_TRIGGER; t2: 'SQLITE_DROP_TRIGGER'; t3: 'Trigger Name'; t4: 'Table Name'), (a2: SQLITE_DROP_VIEW; t2: 'SQLITE_DROP_VIEW'; t3: 'View Name'), (a2: SQLITE_INSERT; t2: 'SQLITE_INSERT'; t3: 'Table Name'), (a2: SQLITE_PRAGMA; t2: 'SQLITE_PRAGMA'; t3: 'Pragma Name'; t4: '1st arg or NULL'), (a2: SQLITE_READ; t2: 'SQLITE_READ'; t3: 'Table Name'; t4: 'Column Name'), (a2: SQLITE_SELECT; t2: 'SQLITE_SELECT'), (a2: SQLITE_TRANSACTION; t2: 'SQLITE_TRANSACTION'), (a2: SQLITE_UPDATE; t2: 'SQLITE_UPDATE'; t3: 'Table Name'; t4: 'Column Name'), (a2: SQLITE_ATTACH; t2: 'SQLITE_ATTACH'; t3: 'Filename'), (a2: SQLITE_DETACH; t2: 'SQLITE_DETACH'; t3: 'Database Name'), (a2: SQLITE_ALTER_TABLE; t2: 'SQLITE_ALTER_TABLE'; t3: 'Database Name'; t4: 'Table Name'), (a2: SQLITE_REINDEX; t2: 'SQLITE_REINDEX'; t3: 'Index Name'), (a2: SQLITE_ANALYZE; t2: 'SQLITE_ANALYZE'; t3: 'Table Name'), (a2: SQLITE_CREATE_VTABLE; t2: 'SQLITE_CREATE_VTABLE'; t3: 'Table Name'; t4: 'Module Name'), (a2: SQLITE_DROP_VTABLE; t2: 'SQLITE_DROP_VTABLE'; t3: 'Table Name'; t4: 'Module Name'), (a2: SQLITE_FUNCTION; t2: 'SQLITE_FUNCTION'; t3: 'Function Name') ); function Authorizer_Callback( UserData: Pointer; Arg2: Integer; Arg3: PAnsiChar; Arg4: PAnsiChar; Arg5: PAnsiChar; Arg6: PAnsiChar): Integer; var i: Integer; begin { Arg2 contains the authorizer action. Resolve the text information. } i := Low(a); repeat if a[i].a2 = Arg2 then Break; Inc(i); until i > High(a); if i <= High(a) then begin { Arg2 always contains the authorizer action. } WriteLn(a[i].t2, ' (', i, ')'); { Arg3 and Arg4 are variable strings, depending on the Arg2 action. } if Assigned(a[i].t3) then WriteLn(a[i].t3, ': ', Arg3); if Assigned(a[i].t4) then WriteLn(a[i].t4, ': ', Arg4); { Arg5 always contains the database name. } WriteLn('Database: ', Arg5); { Arg6 contains the innermost trigger name, if assigned. } if Assigned(Arg6) then WriteLn('Trigger: ', Arg6); end else begin { In case new actions are added which are not yet covered here. } WriteLn('Invalid Arg2: ', i); end; Result := SQLITE_OK; // Authorize all actions. end; //------------------------------------------------------------------------------ var DB: sqlite3; procedure Exec(const SQL: AnsiString); begin WriteLn; WriteLn('SQL: ', SQL); sqlite3_exec_fast(DB, SQL); end; begin DeleteFile('test.db3'); sqlite3_open('test.db3', @DB); sqlite3_set_authorizer(DB, Authorizer_Callback, nil); Exec('create table t(a)'); Exec('insert into t values(1)'); Exec('insert into t values(2)'); Exec('update t set a = 3'); Exec('delete from t'); { You can also use the authorizer callback to intercept custom pragmas. } Exec('PRAGMA custom="value and more"'); sqlite3_check(sqlite3_close(DB), DB); WriteLn; WriteLn('Done - Press ENTER to Exit'); ReadLn; end.