Skip to content
Permalink
Browse files

introducing TIMELOGUNIX() built-in SQLite3 function

returning Unix Epoch seconds from a TTimeLog value
  • Loading branch information...
Arnaud Bouchez
Arnaud Bouchez committed Jun 13, 2019
1 parent 03c7309 commit 171df20debc44ade18b1a4df044a0e6f8c36356d
Showing with 29 additions and 14 deletions.
  1. +10 −8 SynCommons.pas
  2. +18 −5 SynSQLite3.pas
  3. +1 −1 SynopseCommit.inc
@@ -7137,8 +7137,9 @@ function SimpleDynArrayLoadFrom(Source: PAnsiChar; aTypeInfo: pointer;
// is much faster than creating a temporary dynamic array to load the data
// - will return nil if no or invalid data, or a pointer to the integer
// array otherwise, with the items number stored in Count
// - a bit faster than SimpleDynArrayLoadFrom(Source,TypeInfo(TIntegerDynArray),Count)
function IntegerDynArrayLoadFrom(Source: PAnsiChar; var Count: integer): PIntegerArray;
// - sligtly faster than SimpleDynArrayLoadFrom(Source,TypeInfo(TIntegerDynArray),Count)
function IntegerDynArrayLoadFrom(Source: PAnsiChar; var Count: integer;
NoHash32Check: boolean=false): PIntegerArray;

/// search in a RawUTF8 dynamic array BLOB content as stored by TDynArray.SaveTo
// - same as search within TDynArray.LoadFrom() with no memory allocation nor
@z: rep ret
@0: lea eax, NULL_SHORTSTRING
end;
{$endif}
{$endif HASINLINENOTX86}

{$ifdef PUREPASCAL} // for proper inlining
function IdemPropNameUSameLen(P1,P2: PUTF8Char; P1P2Len: PtrInt): boolean;
mov dword ptr [ebx].TDiv100Rec.M, ecx
pop ebx
end;
{$endif}
{$endif HASINLINENOTX86}

function UInt3DigitsToUTF8(Value: Cardinal): RawUTF8;
begin
result := @Hash[1]; // returns valid Source content
end;

function IntegerDynArrayLoadFrom(Source: PAnsiChar; var Count: integer): PIntegerArray;
function IntegerDynArrayLoadFrom(Source: PAnsiChar; var Count: integer;
NoHash32Check: boolean): PIntegerArray;
var Hash: PCardinalArray absolute Source;
begin
result := nil;
if (Source=nil) or (Source[0]<>#4) or (Source[1]<>#0) then
exit; // invalid Source content
inc(Source,2);
Count := FromVarUInt32(PByte(Source)); // dynamic array count
if (Count<>0) and (Hash32(@Hash[1],Count*SizeOf(Integer))=Hash[0]) then
if (Count<>0) and (NoHash32Check or (Hash32(@Hash[1],Count*4)=Hash[0])) then
result := @Hash[1]; // returns valid Source content
end;

end;
inc(Source,2);
Count := FromVarUInt32(PByte(Source)); // dynamic array count
inc(Source,SizeOf(cardinal)); // ignore security checksum
inc(Source,SizeOf(cardinal)); // ignore Hash32 security checksum
for result := 0 to Count-1 do begin
Len := FromVarUInt32(PByte(Source));
if CaseSensitive then begin
@1: test dl, dl
setz al
end;
{$endif}
{$endif HASINLINENOTX86}

function StrCompL(P1,P2: PUTF8Char; L, Default: Integer): PtrInt;
var i: PtrInt;
@@ -274,7 +274,7 @@ interface
/// internaly store a SQLite3 Backup process handle
TSQLite3Backup = type PtrUInt;

/// internaly store any array of SQLite3 value
/// internaly store of SQLite3 values, as used by TSQLFunctionFunc
TSQLite3ValueArray = array[0..63] of TSQLite3Value;

const
@@ -981,9 +981,8 @@ TSQLite3Module = record
// must be prepared for attempts to delete or modify rows of the table out
// from other existing cursors. If the virtual table cannot accommodate such
// changes, the xUpdate() method must return an error code.
xUpdate: function(var pVTab: TSQLite3VTab;
nArg: Integer; var ppArg: TSQLite3ValueArray;
var pRowid: Int64): Integer; cdecl;
xUpdate: function(var pVTab: TSQLite3VTab; nArg: Integer;
var ppArg: TSQLite3ValueArray; var pRowid: Int64): Integer; cdecl;
/// Begins a transaction on a virtual table
// - This method is always followed by one call to either the xCommit or
// xRollback method.
@@ -3663,6 +3662,18 @@ procedure InternalTimeLog(Context: TSQLite3FunctionContext;
RawUTF8ToSQlite3Context(TimeLog.Text(True,'T'),Context,false);
end;

procedure InternalTimeLogUnix(Context: TSQLite3FunctionContext;
argc: integer; var argv: TSQLite3ValueArray); cdecl;
var TimeLog: TTimeLogBits;
begin
if argc<>1 then begin
ErrorWrongNumberOfArgs(Context);
exit;
end;
TimeLog.Value := sqlite3.value_int64(argv[0]);
sqlite3.result_int64(Context,TimeLog.ToUnixTime);
end;

procedure InternalRank(Context: TSQLite3FunctionContext;
argc: integer; var argv: TSQLite3ValueArray); cdecl;
// supplies the same "RANK" internal function as proposed in
@@ -4636,7 +4647,7 @@ function TSQLDataBase.DBOpen: integer;
end;
// always try to check for proper database content (and password)
if not ExecuteNoException('select count(*) from sqlite_master') then begin
Result := SQLITE_NOTADB; // likely a password error
result := SQLITE_NOTADB; // likely a password error
sqlite3.close(fDB); // should always be closed, even on failure
fDB := 0;
exit;
@@ -4653,6 +4664,8 @@ function TSQLDataBase.DBOpen: integer;
sqlite3.create_function(DB,'MOD',2,SQLITE_ANY,nil,InternalMod,nil,nil);
// register TIMELOG(), returning a ISO-8601 date/time from TTimeLog value
sqlite3.create_function(DB,'TIMELOG',1,SQLITE_ANY,nil,InternalTimeLog,nil,nil);
// register TIMELOGUNIX(), returning Unix Epoch seconds from TTimeLog value
sqlite3.create_function(DB,'TIMELOGUNIX',1,SQLITE_ANY,nil,InternalTimeLogUnix,nil,nil);
// some user functions
sqlite3.create_function(DB,'SOUNDEX',1,SQLITE_UTF8,nil,InternalSoundex,nil,nil);
sqlite3.create_function(DB,'SOUNDEXFR',1,SQLITE_UTF8,nil,InternalSoundexFr,nil,nil);
@@ -1 +1 @@
'1.18.5241'
'1.18.5242'

0 comments on commit 171df20

Please sign in to comment.
You can’t perform that action at this time.