Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | {4633} added soft_heap_limit64() SQLite3 API and fixed config() call on external dll |
---|---|
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d5ff204eea2843f48c8e22900fa22878 |
User & Date: | ab 2018-06-22 10:42:25 |
2018-06-22
| ||
11:32 | {4634} globallly cached current date/time information with 8-16ms resolution check-in: 5db4db365c user: ab tags: trunk | |
10:42 | {4633} added soft_heap_limit64() SQLite3 API and fixed config() call on external dll check-in: d5ff204eea user: ab tags: trunk | |
10:18 | {4632} enhancements to FPC/Linux support check-in: 35c13ca271 user: ab tags: trunk | |
Changes to SynSQLite3.pas.
2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 .... 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 .... 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 .... 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 .... 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 .... 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 .... 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 .... 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 .... 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 |
/// serialize a database // - returns a pointer to memory that is a serialization of the Schema // database on database connection DB // - if Size is not nil, then the size of the database in bytes is written into Size^ // - for an ordinary on-disk database file, the serialization is just a copy // of the disk file; for an in-memory database or a "TEMP" database, the // serialization is the same sequence of bytes which would be written to disk // if that database where backed up to disk. // - caller is responsible for freeing the returned value (using free_) // to avoid a memory leak serialize: function(DB: TSQLite3DB; Schema: PUTF8Char; Size: PInt64; Flags: integer): pointer; cdecl; /// deserialize a database // - causes the database connection DB to disconnect from database Schema // and then reopen Schema as an in-memory database based on the serialization // contained in Data; the serialized database Data is DBSize bytes in size // - BufSize is the size of the buffer Data, which might be larger than DBSize deserialize: function(DB: TSQLite3DB; Schema: PUTF8Char; Data: pointer; DBSize, BufSize: Int64; Flags: integer): pointer; cdecl; /// used to make global configuration changes to current database config: function(operation: integer): integer; {$ifndef DELPHI5OROLDER}cdecl varargs;{$endif} /// used to make global configuration changes to current database connection db_config: function(DestDB: TSQLite3DB; operation: integer): integer; {$ifndef DELPHI5OROLDER}cdecl varargs;{$endif} ................................................................................ fLibraryName: TFileName; public /// initialize the specified external library // - raise an ESQLite3Exception on error constructor Create(const LibraryName: TFileName=SQLITE_LIBRARY_DEFAULT_NAME); reintroduce; /// unload the external library destructor Destroy; override; /// will change the SQLite3 configuration to use Delphi/FPC memory manager // - overriden method which does nothing on some platforms found unstable procedure ForceToUseSharedMemoryManager; override; published property LibraryName: TFileName read fLibraryName; end; /// an internal function which calls Freemem(p) // - can be used to free some PUTF8Char pointer allocated by Delphi Getmem() ................................................................................ {$endif} constructor TSQLDataBase.Create(const aFileName: TFileName; const aPassword: RawUTF8; aOpenV2Flags, aDefaultCacheSize,aDefaultPageSize: integer); var result: integer; begin if sqlite3=nil then raise ESQLite3Exception.Create('No SQLite3 libray available: you shall '+ 'either add SynSQLite3Static to your project uses clause, '+ 'or run sqlite3 := TSQLite3LibraryDynamic.Create(..)'); {$ifdef WITHLOG} fLog := SynSQLite3Log; // leave fLog=nil if no Logging wanted fLogResultMaximumSize := 512; {$endif} if SysUtils.Trim(aFileName)='' then raise ESQLite3Exception.CreateUTF8('%.Create('''')',[self]); if aOpenV2Flags=0 then ................................................................................ for i := 0 to fSQLFunctions.Count-1 do TSQLDataBaseSQLFunction(fSQLFunctions.List[i]).CreateFunction(DB); {$ifdef WITHLOG} i := CacheSize; if i<0 then i := (-i) shr 10 else i := PageSize*CacheSize; FPCLog.Log(sllDB,'"%" database file of % opened with PageSize=% and CacheSize=% (%)', [FileName,KB(GetFileSize),PageSize,CacheSize,KB(i)],self); {$endif} end; function TSQLDataBase.GetUserVersion: cardinal; begin result := ExecuteNoExceptionInt64('PRAGMA user_version'); ................................................................................ FormatUTF8('% with %ternal MM',[fVersionText,MM[fUseInternalMM]],result); end; { TSQLite3LibraryDynamic } const SQLITE3_ENTRIES: array[0..89] of TFileName = ('initialize','shutdown','open','open_v2','key','rekey','close', 'libversion','errmsg','extended_errcode', 'create_function','create_function_v2', 'create_collation','last_insert_rowid','busy_timeout','busy_handler', 'prepare_v2','finalize','next_stmt','reset','stmt_readonly','step', 'column_count','column_type','column_decltype','column_name','column_bytes', 'column_value','column_double','column_int','column_int64','column_text', ................................................................................ 'aggregate_context','bind_text','bind_blob','bind_zeroblob','bind_double', 'bind_int','bind_int64','bind_null','clear_bindings','bind_parameter_count', 'blob_open','blob_reopen','blob_close','blob_read','blob_write','blob_bytes', 'create_module_v2','declare_vtab','set_authorizer','update_hook', 'commit_hook','rollback_hook','changes','total_changes','malloc', 'realloc', 'free','memory_used','memory_highwater','trace_v2','limit', 'backup_init','backup_step','backup_finish','backup_remaining', 'backup_pagecount','config','db_config','serialize','deserialize'); constructor TSQLite3LibraryDynamic.Create(const LibraryName: TFileName); var P: PPointerArray; i: integer; begin fLibraryName := LibraryName; {$ifdef MSWINDOWS} ................................................................................ fHandle := TLibHandle(dlopen(PChar(LibraryName),0)); if fHandle=TLibHandle(nil) then {$else} fHandle := LoadLibrary({$ifndef FPC}pointer{$endif}(LibraryName)); if fHandle=0 then {$endif} {$endif MSWINDOWS} raise ESQLite3Exception.CreateFmt('Unable to load %s - %s', [LibraryName,SysErrorMessage(GetLastError)]); P := @@initialize; for i := 0 to High(SQLITE3_ENTRIES) do P^[i] := {$ifdef BSDNOTDARWIN}dlsym{$else}GetProcAddress{$endif}( fHandle,PChar('sqlite3_'+SQLITE3_ENTRIES[i])); if not Assigned(initialize) or not Assigned(libversion) or not Assigned(open) or not Assigned(close) or not Assigned(create_function) or not Assigned(prepare_v2) or not Assigned(create_module_v2) then begin ................................................................................ {$ifdef BSDNOTDARWIN} dlclose(fHandle); fHandle := TLibHandle(nil); {$else} FreeLibrary(fHandle); fHandle := 0; {$endif} raise ESQLite3Exception.CreateFmt('TOO OLD %s - need 3.7 at least!',[LibraryName]); end; // some APIs like config() key() or trace() may not be available inherited Create; // set fVersionNumber/fVersionText {$ifdef WITHLOG} SynSQLite3Log.Add.Log(sllInfo,'Loaded external % version %',[LibraryName,Version]); {$endif} end; ................................................................................ if fHandle<>0 then FreeLibrary(fHandle); {$endif} inherited; end; procedure TSQLite3LibraryDynamic.ForceToUseSharedMemoryManager; begin {$ifndef CPU64DELPHI} // buggy as usual inherited ForceToUseSharedMemoryManager; {$endif} end; initialization finalization FreeAndNil(sqlite3); // sqlite3.Free is not reintrant e.g. as .bpl in IDE end. |
| > > > > > > > > > > > > > > > > > > > < < < | | | | | > | | | | > < < < < < < < |
2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 .... 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 .... 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 .... 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 .... 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 .... 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 .... 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 .... 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 .... 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 |
/// serialize a database // - returns a pointer to memory that is a serialization of the Schema // database on database connection DB // - if Size is not nil, then the size of the database in bytes is written into Size^ // - for an ordinary on-disk database file, the serialization is just a copy // of the disk file; for an in-memory database or a "TEMP" database, the // serialization is the same sequence of bytes which would be written to disk // if that database where backed up to disk // - caller is responsible for freeing the returned value (using free_) // to avoid a memory leak serialize: function(DB: TSQLite3DB; Schema: PUTF8Char; Size: PInt64; Flags: integer): pointer; cdecl; /// deserialize a database // - causes the database connection DB to disconnect from database Schema // and then reopen Schema as an in-memory database based on the serialization // contained in Data; the serialized database Data is DBSize bytes in size // - BufSize is the size of the buffer Data, which might be larger than DBSize deserialize: function(DB: TSQLite3DB; Schema: PUTF8Char; Data: pointer; DBSize, BufSize: Int64; Flags: integer): pointer; cdecl; /// sets and/or queries the soft limit on the amount of heap memory // that may be allocated by SQLite // - SQLite strives to keep heap memory utilization below the soft heap limit // by reducing the number of pages held in the page cache as heap memory usages // approaches the limit. The soft heap limit is "soft" because even though // SQLite strives to stay below the limit, it will exceed the limit rather // than generate an SQLITE_NOMEM error. In other words, the soft heap limit // is advisory only // - The return value from soft_heap_limit64() is the size of the soft heap // limit prior to the call, or negative in the case of an error. If the // argument N is negative then no change is made to the soft heap limit. // Hence, the current size of the soft heap limit can be determined by // invoking soft_heap_limit64() with a negative argument // - This function is useful when you have many SQLite databases open at // the same time, as the cache-size setting is per-database (connection), // while this limit is global for the process, so this allows to limit the // total cache size soft_heap_limit64: function(N: Int64): Int64; cdecl; /// used to make global configuration changes to current database config: function(operation: integer): integer; {$ifndef DELPHI5OROLDER}cdecl varargs;{$endif} /// used to make global configuration changes to current database connection db_config: function(DestDB: TSQLite3DB; operation: integer): integer; {$ifndef DELPHI5OROLDER}cdecl varargs;{$endif} ................................................................................ fLibraryName: TFileName; public /// initialize the specified external library // - raise an ESQLite3Exception on error constructor Create(const LibraryName: TFileName=SQLITE_LIBRARY_DEFAULT_NAME); reintroduce; /// unload the external library destructor Destroy; override; published property LibraryName: TFileName read fLibraryName; end; /// an internal function which calls Freemem(p) // - can be used to free some PUTF8Char pointer allocated by Delphi Getmem() ................................................................................ {$endif} constructor TSQLDataBase.Create(const aFileName: TFileName; const aPassword: RawUTF8; aOpenV2Flags, aDefaultCacheSize,aDefaultPageSize: integer); var result: integer; begin if sqlite3=nil then raise ESQLite3Exception.CreateUTF8('%.Create: No SQLite3 libray available'+ ' - you shall either add SynSQLite3Static to your project uses clause, '+ 'or run sqlite3 := TSQLite3LibraryDynamic.Create(..)',[self]); {$ifdef WITHLOG} fLog := SynSQLite3Log; // leave fLog=nil if no Logging wanted fLogResultMaximumSize := 512; {$endif} if SysUtils.Trim(aFileName)='' then raise ESQLite3Exception.CreateUTF8('%.Create('''')',[self]); if aOpenV2Flags=0 then ................................................................................ for i := 0 to fSQLFunctions.Count-1 do TSQLDataBaseSQLFunction(fSQLFunctions.List[i]).CreateFunction(DB); {$ifdef WITHLOG} i := CacheSize; if i<0 then i := (-i) shr 10 else i := PageSize*CacheSize; FPCLog.Log(sllDB,'"%" database file (%) opened with PageSize=% CacheSize=% (%)', [FileName,KB(GetFileSize),PageSize,CacheSize,KB(i)],self); {$endif} end; function TSQLDataBase.GetUserVersion: cardinal; begin result := ExecuteNoExceptionInt64('PRAGMA user_version'); ................................................................................ FormatUTF8('% with %ternal MM',[fVersionText,MM[fUseInternalMM]],result); end; { TSQLite3LibraryDynamic } const SQLITE3_ENTRIES: array[0..90] of TFileName = ('initialize','shutdown','open','open_v2','key','rekey','close', 'libversion','errmsg','extended_errcode', 'create_function','create_function_v2', 'create_collation','last_insert_rowid','busy_timeout','busy_handler', 'prepare_v2','finalize','next_stmt','reset','stmt_readonly','step', 'column_count','column_type','column_decltype','column_name','column_bytes', 'column_value','column_double','column_int','column_int64','column_text', ................................................................................ 'aggregate_context','bind_text','bind_blob','bind_zeroblob','bind_double', 'bind_int','bind_int64','bind_null','clear_bindings','bind_parameter_count', 'blob_open','blob_reopen','blob_close','blob_read','blob_write','blob_bytes', 'create_module_v2','declare_vtab','set_authorizer','update_hook', 'commit_hook','rollback_hook','changes','total_changes','malloc', 'realloc', 'free','memory_used','memory_highwater','trace_v2','limit', 'backup_init','backup_step','backup_finish','backup_remaining', 'backup_pagecount','serialize','deserialize','soft_heap_limit64', 'config','db_config'); constructor TSQLite3LibraryDynamic.Create(const LibraryName: TFileName); var P: PPointerArray; i: integer; begin fLibraryName := LibraryName; {$ifdef MSWINDOWS} ................................................................................ fHandle := TLibHandle(dlopen(PChar(LibraryName),0)); if fHandle=TLibHandle(nil) then {$else} fHandle := LoadLibrary({$ifndef FPC}pointer{$endif}(LibraryName)); if fHandle=0 then {$endif} {$endif MSWINDOWS} raise ESQLite3Exception.CreateUTF8('%.Create: Unable to load % - %', [self,LibraryName,SysErrorMessage(GetLastError)]); P := @@initialize; for i := 0 to High(SQLITE3_ENTRIES) do P^[i] := {$ifdef BSDNOTDARWIN}dlsym{$else}GetProcAddress{$endif}( fHandle,PChar('sqlite3_'+SQLITE3_ENTRIES[i])); if not Assigned(initialize) or not Assigned(libversion) or not Assigned(open) or not Assigned(close) or not Assigned(create_function) or not Assigned(prepare_v2) or not Assigned(create_module_v2) then begin ................................................................................ {$ifdef BSDNOTDARWIN} dlclose(fHandle); fHandle := TLibHandle(nil); {$else} FreeLibrary(fHandle); fHandle := 0; {$endif} raise ESQLite3Exception.CreateUTF8('%.Create: TOO OLD % % - need 3.7 at least!', [LibraryName,Version]); end; // some APIs like config() key() or trace() may not be available inherited Create; // set fVersionNumber/fVersionText {$ifdef WITHLOG} SynSQLite3Log.Add.Log(sllInfo,'Loaded external % version %',[LibraryName,Version]); {$endif} end; ................................................................................ if fHandle<>0 then FreeLibrary(fHandle); {$endif} inherited; end; initialization finalization FreeAndNil(sqlite3); // sqlite3.Free is not reintrant e.g. as .bpl in IDE end. |
Changes to SynopseCommit.inc.
1 |
'1.18.4632'
|
| |
1 |
'1.18.4633'
|