mORMot and Open Source friends
Check-in [ad74af8201]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:added an optional behavior parameter to TSQLDataBase.TransactionBegin method
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: ad74af8201a131d5c40de9d6a01057bcf7c7be18
User & Date: G018869 2012-01-03 10:05:16
Context
2012-01-03
12:39
  • added sqlite3_changes() and sqlite3_total_changes() function prototypes
  • added an optional behavior parameter to TSQLDataBase.TransactionBegin method
  • engine is now compiled including tracing within the FTS3 extension - added sqlite3_trace() function prototype to register your own tracing callback
check-in: 0d56098dfe user: G018869 tags: trunk
10:05
added an optional behavior parameter to TSQLDataBase.TransactionBegin method check-in: ad74af8201 user: G018869 tags: trunk
2011-12-21
18:47
fixed some minor compilation errors check-in: 4f2294edaa user: User tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to SynSQLite3.pas.

93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
....
1869
1870
1871
1872
1873
1874
1875


























1876
1877
1878
1879
1880
1881
1882
....
1977
1978
1979
1980
1981
1982
1983
1984

1985
1986
1987
1988
1989
1990
1991
1992
....
2875
2876
2877
2878
2879
2880
2881
2882



2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
  - TSQLDatabase constructors now accepts an optional Password parameter,
    associated to the supplied file name, in order to use database encryption

  Version 1.16
  - updated SQLite3 engine to version 3.7.9
  - new IsSQLite3FileEncrypted() function
  - new parameter in TSQLDataBase.ExecuteJSON, LockJSON, UnLockJSON methods,
    for an optional integer pointer, to return the count of row data   


    Todo:
    - port to systems other than Delphi+Win32 (use external DLL?)
}

{$I Synopse.inc} // define HASINLINE USETYPEINFO CPU32 CPU64 OWNNORMTOUPPER

................................................................................
  // local or shared TSQLRequest
  // - the TSQLRequest may be shared and prepared before the call for even
  // faster access than with a local TSQLRequest 
  // - no TSQLDataBase or higher levels objects can be used inside this method,
  // since all locking and try..finally protection is outside it
  // - can optionnaly trigger a ESQLException on any error
  TOnSQLStoredProc = procedure(Statement: TSQLRequest) of object;



























  /// simple wrapper for direct SQLite3 database manipulation
  // - embed the SQLite3 database calls into a common object
  // - thread-safe call of all SQLite3 queries (SQLITE_THREADSAFE 0 in sqlite.c)
  // - can cache last results for SELECT statements, if property UseCache is true:
  //  this can speed up most read queries, for web server or client UI e.g.
  TSQLDataBase = class
................................................................................
    procedure Execute(const aSQL: RawUTF8; out ID: RawUTF8); overload;
    /// Execute one SQL statement returning its results in JSON format
    // - the BLOB data is encoded as '"\uFFF0base64encodedbinary"'
    function ExecuteJSON(const aSQL: RawUTF8; Expand: boolean=false; aResultCount: PPtrInt=nil): RawUTF8;
    {{ begin a transaction
     - Execute SQL statements with Execute() procedure below
     - must be ended with Commit on success
     - must be aborted with Rollback after an ESQLException raised }

    procedure TransactionBegin;
    {{ end a transaction: write all Execute() statements to the disk }
    procedure Commit;
    {{ abort a transaction: restore the previous state of the database }
    procedure RollBack;
    {{ return the last Insert Rowid }
    function LastInsertRowID: Int64;
    {{ get all table names contained in this database file }
................................................................................
begin
  if (self=nil) or not fTransactionActive then
    exit;
  Execute('ROLLBACK TRANSACTION;');
  fTransactionActive := false;
end;

procedure TSQLDataBase.TransactionBegin;



begin
  if self=nil then 
    exit; // avoid GPF in case of call from a static-only server
  if fTransactionActive then begin
    Execute('ROLLBACK TRANSACTION;');
    fTransactionActive := false;
  end;
  Execute('BEGIN TRANSACTION;');
  fTransactionActive := true;
end;

procedure TSQLDataBase.Commit;
begin
  if (Self<>nil) and fTransactionActive then begin
    Execute('COMMIT TRANSACTION;');






|
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
>
|







 







|
>
>
>

|





|







93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
....
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
....
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
....
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
  - TSQLDatabase constructors now accepts an optional Password parameter,
    associated to the supplied file name, in order to use database encryption

  Version 1.16
  - updated SQLite3 engine to version 3.7.9
  - new IsSQLite3FileEncrypted() function
  - new parameter in TSQLDataBase.ExecuteJSON, LockJSON, UnLockJSON methods,
    for an optional integer pointer, to return the count of row data
  - added an optional behavior parameter to TSQLDataBase.TransactionBegin method

    Todo:
    - port to systems other than Delphi+Win32 (use external DLL?)
}

{$I Synopse.inc} // define HASINLINE USETYPEINFO CPU32 CPU64 OWNNORMTOUPPER

................................................................................
  // local or shared TSQLRequest
  // - the TSQLRequest may be shared and prepared before the call for even
  // faster access than with a local TSQLRequest 
  // - no TSQLDataBase or higher levels objects can be used inside this method,
  // since all locking and try..finally protection is outside it
  // - can optionnaly trigger a ESQLException on any error
  TOnSQLStoredProc = procedure(Statement: TSQLRequest) of object;

  {{ TSQLDataBase.TransactionBegin can be deferred, immediate, or exclusive
   - tbDeferred means that no locks are acquired on the database until the
   database is first accessed. Thus with a deferred transaction, the BEGIN
   statement itself does nothing to the filesystem. Locks are not acquired
   until the first read or write operation. The first read operation against
   a database creates a SHARED lock and the first write operation creates a
   RESERVED lock. Because the acquisition of locks is deferred until they are
   needed, it is possible that another thread or process could create a
   separate transaction and write to the database after the BEGIN on the
   current thread has executed.
   - If the transaction is tbImmediate, then RESERVED locks are acquired
   on all databases as soon as the BEGIN command is executed, without waiting
   for the database to be used. After a BEGIN IMMEDIATE, no other database
   connection will be able to write to the database or do a BEGIN IMMEDIATE
   or BEGIN EXCLUSIVE. Other processes can continue to read from the database,
   however.
   - A tbExclusive transaction causes EXCLUSIVE locks to be acquired on all
   databases. After a BEGIN EXCLUSIVE, no other database connection except
   for read_uncommitted connections will be able to read the database and
   no other connection without exception will be able to write the database
   until the transaction is complete. }
  TSQLDataBaseTransactionBehaviour = (
    tbDeferred,
    tbImmediate,
    tbExclusive);

  /// simple wrapper for direct SQLite3 database manipulation
  // - embed the SQLite3 database calls into a common object
  // - thread-safe call of all SQLite3 queries (SQLITE_THREADSAFE 0 in sqlite.c)
  // - can cache last results for SELECT statements, if property UseCache is true:
  //  this can speed up most read queries, for web server or client UI e.g.
  TSQLDataBase = class
................................................................................
    procedure Execute(const aSQL: RawUTF8; out ID: RawUTF8); overload;
    /// Execute one SQL statement returning its results in JSON format
    // - the BLOB data is encoded as '"\uFFF0base64encodedbinary"'
    function ExecuteJSON(const aSQL: RawUTF8; Expand: boolean=false; aResultCount: PPtrInt=nil): RawUTF8;
    {{ begin a transaction
     - Execute SQL statements with Execute() procedure below
     - must be ended with Commit on success
     - must be aborted with Rollback after an ESQLException raised
    - The default transaction behavior is tbDeferred }
    procedure TransactionBegin(aBehavior: TSQLDataBaseTransactionBehaviour = tbDeferred);
    {{ end a transaction: write all Execute() statements to the disk }
    procedure Commit;
    {{ abort a transaction: restore the previous state of the database }
    procedure RollBack;
    {{ return the last Insert Rowid }
    function LastInsertRowID: Int64;
    {{ get all table names contained in this database file }
................................................................................
begin
  if (self=nil) or not fTransactionActive then
    exit;
  Execute('ROLLBACK TRANSACTION;');
  fTransactionActive := false;
end;

procedure TSQLDataBase.TransactionBegin(aBehavior: TSQLDataBaseTransactionBehaviour = tbDeferred);
const
  TBTOKENS: array[TSQLDataBaseTransactionBehaviour] of RawUTF8 = (
    '', 'IMMEDIATE ', 'EXCLUSIVE '); // see http://www.sqlite.org/lang_transaction.html
begin
  if self=nil then
    exit; // avoid GPF in case of call from a static-only server
  if fTransactionActive then begin
    Execute('ROLLBACK TRANSACTION;');
    fTransactionActive := false;
  end;
  Execute('BEGIN '+TBTOKENS[aBehavior]+'TRANSACTION;');
  fTransactionActive := true;
end;

procedure TSQLDataBase.Commit;
begin
  if (Self<>nil) and fTransactionActive then begin
    Execute('COMMIT TRANSACTION;');