📄 asgsqlite3.pas
字号:
Procedure TFResult.Delete(Index: integer);
Var
ptr: Pointer;
Begin
DebugEnter('TFResult.Delete');
If Not ((Index < 0) Or (Index >= Data.Count)) Then
Begin
ptr := Data.Items[Index];
If ptr <> Nil Then
FreeMem(ptr, FBufSize);
Data.Delete(Index);
Bookmark.Delete(Index);
RowId.Delete(Index);
End;
DebugLeave('TFResult.Delete');
End;
//==============================================================================
// Returns a row from the resultset
//==============================================================================
Function TFResult.GetData(Index: integer): Pointer;
Begin
DebugEnter('TFResult.GetData');
If (Index < 0) Or (Index >= Data.Count) Then
GetData := Nil
Else
GetData := Data.Items[Index];
DebugLeave('TFResult.GetData');
End;
Function TFResult.GetBookmark(Index: integer): integer;
Begin
DebugEnter('TFResult.GetBookmark');
If (Index < 0) Or (Index >= Data.Count) Then
GetBookmark := -1
Else
GetBookmark := integer(Bookmark.Items[Index]);
DebugLeave('TFResult.GetBookmark');
End;
Function TFResult.GetRowId(Index: integer): integer;
Begin
DebugEnter('TFResult.GetRowId');
If (Index < 0) Or (Index >= RowId.Count) Then
GetRowId := -1
Else
GetRowId := integer(RowId.Items[Index]);
DebugLeave('TFResult.GetRowId');
End;
Function TFResult.Count: integer;
Begin
Count := Data.Count;
End;
Function TFResult.IndexOf(TheBookMark: Pointer): integer;
Begin
Result := Bookmark.IndexOf(TheBookMark);
End;
//============================================================================== ASQLITEDB
Procedure TASQLite3DB.Notification(AComponent: TComponent; Operation: TOperation);
Begin
{$IFDEF DEBUG_VERY_LOUD}
DebugEnter('TASQLite3DB.Notification');
{$ENDIF}
// Application.ProcessMessages;
If Assigned(AComponent) Then
Begin
If (Operation = opRemove) Then
Begin
If (AComponent Is TASQLite3Pragma) Then
Begin
If Assigned(FASQLitePragma) Then
Begin
If TASQLite3Pragma(AComponent) = FASQLitePragma Then
FASQLitePragma := Nil;
End;
End
Else If (AComponent Is TASQLite3Log) Then
Begin
If Assigned(FASQLiteLog) Then
Begin
If TASQLite3Log(AComponent) = FASQLiteLog Then
FASQLiteLog := Nil;
End;
End
Else If (AComponent Is TASQLite3InlineSQL) Then
Begin
If Assigned(FInlineSQL) Then
Begin
If TASQLite3InlineSQL(AComponent) = FInlineSQL Then
FInlineSQL := Nil;
End;
End;
End;
End;
Inherited;
{$IFDEF DEBUG_VERY_LOUD}
DebugLeave('TASQLite3DB.Notification');
{$ENDIF}
End;
Function TASQLite3DB.LoadLibs: boolean;
Begin
Try
DebugEnter('TASQLite3DB.LoadLibs');
If Not (DecimalSeparator In ['.', ',']) Then
DecimalSeparator := '.';
Debug('loading sqlite lib');
{$IFNDEF SQLite_Static}
Debug(PAnsiChar(DriverDLL));
Result := false;
DLLHandle := LoadLibrary(PAnsiChar(DriverDLL)); //JohnLito
If DLLHandle <> 0 Then
Begin
{$IFDEF UseSQLiteCrypt}
@SQLite3_Key := GetProcAddress(DLLHandle, 'sqlite3_key');
@SQLite3_Rekey := GetProcAddress(DLLHandle, 'sqlite3_rekey');
{$ENDIF}
@SQLite3_Open := GetProcAddress(DLLHandle, 'sqlite3_open');
If Not Assigned(@SQLite3_Open) Then exit;
@SQLite3_Close := GetProcAddress(DLLHandle, 'sqlite3_close');
If Not Assigned(@SQLite3_Close) Then exit;
@SQLite3_Exec := GetProcAddress(DLLHandle, 'sqlite3_exec');
If Not Assigned(@SQLite3_Exec) Then exit;
@SQLite3_LibVersion := GetProcAddress(DLLHandle, 'sqlite3_libversion');
If Not Assigned(@SQLite3_LibVersion) Then exit;
@SQLite3_ErrorString := GetProcAddress(DLLHandle, 'sqlite3_errmsg');
If Not Assigned(@SQLite3_ErrorString) Then exit;
@SQLite3_GetTable := GetProcAddress(DLLHandle, 'sqlite3_get_table');
If Not Assigned(@SQLite3_GetTable) Then exit;
@SQLite3_FreeTable := GetProcAddress(DLLHandle, 'sqlite3_free_table');
If Not Assigned(@SQLite3_FreeTable) Then exit;
@SQLite3_FreeMem := GetProcAddress(DLLHandle, 'sqlite3_free');
If Not Assigned(@SQLite3_FreeMem) Then exit;
@SQLite3_Complete := GetProcAddress(DLLHandle, 'sqlite3_complete');
If Not Assigned(@SQLite3_Complete) Then exit;
@SQLite3_LastInsertRow := GetProcAddress(DLLHandle, 'sqlite3_last_insert_rowid');
If Not Assigned(@SQLite3_LastInsertRow) Then exit;
@SQLite3_Cancel := GetProcAddress(DLLHandle, 'sqlite3_interrupt');
If Not Assigned(@SQLite3_Cancel) Then exit;
@SQLite3_BusyTimeout := GetProcAddress(DLLHandle, 'sqlite3_busy_timeout');
If Not Assigned(@SQLite3_BusyTimeout) Then exit;
@SQLite3_BusyHandler := GetProcAddress(DLLHandle, 'sqlite3_busy_handler');
If Not Assigned(@SQLite3_BusyHandler) Then exit;
@SQLite3_Changes := GetProcAddress(DLLHandle, 'sqlite3_changes');
If Not Assigned(@SQLite3_Changes) Then exit;
@SQLite3_Prepare := GetProcAddress(DLLHandle, 'sqlite3_prepare');
If Not Assigned(@SQLite3_Prepare) Then exit;
@SQLite3_Finalize := GetProcAddress(DLLHandle, 'sqlite3_finalize');
If Not Assigned(@SQLite3_Finalize) Then exit;
@SQLite3_Reset := GetProcAddress(DLLHandle, 'sqlite3_reset');
If Not Assigned(@SQLite3_Reset) Then exit;
@SQLite3_Step := GetProcAddress(DLLHandle, 'sqlite3_step');
If Not Assigned(@SQLite3_Step) Then exit;
@SQLite3_Column_blob := GetProcAddress(DLLHandle, 'sqlite3_column_blob');
If Not Assigned(@SQLite3_Column_blob) Then exit;
@SQLite3_Column_bytes := GetProcAddress(DLLHandle, 'sqlite3_column_bytes');
If Not Assigned(@SQLite3_Column_bytes) Then exit;
@SQLite3_Column_count := GetProcAddress(DLLHandle, 'sqlite3_column_count');
If Not Assigned(@SQLite3_Column_count) Then exit;
@SQLite3_Column_decltype := GetProcAddress(DLLHandle, 'sqlite3_column_decltype');
If Not Assigned(@SQLite3_Column_decltype) Then exit;
@SQLite3_Column_double := GetProcAddress(DLLHandle, 'sqlite3_column_double');
If Not Assigned(@SQLite3_Column_double) Then exit;
@SQLite3_Column_int := GetProcAddress(DLLHandle, 'sqlite3_column_int');
If Not Assigned(@SQLite3_Column_int) Then exit;
@SQLite3_Column_int64 := GetProcAddress(DLLHandle, 'sqlite3_column_int64');
If Not Assigned(@SQLite3_Column_int64) Then exit;
@SQLite3_Column_name := GetProcAddress(DLLHandle, 'sqlite3_column_name');
If Not Assigned(@SQLite3_Column_name) Then exit;
@SQLite3_Column_text := GetProcAddress(DLLHandle, 'sqlite3_column_text');
If Not Assigned(@SQLite3_Column_text) Then exit;
@SQLite3_Column_text16 := GetProcAddress(DLLHandle, 'sqlite3_column_text16');
If Not Assigned(@SQLite3_Column_text16) Then exit;
@SQLite3_Column_type := GetProcAddress(DLLHandle, 'sqlite3_column_type');
If Not Assigned(@SQLite3_Column_type) Then exit;
@SQLite3_Bind_Blob := GetProcAddress(DLLHandle, 'sqlite3_bind_blob');
If Not Assigned(@SQLite3_Bind_Blob) Then exit;
@SQLite3_Bind_Text16 := GetProcAddress(DLLHandle, 'sqlite3_bind_text16');
If Not Assigned(@SQLite3_Bind_Text16) Then exit;
@SQLite3_Bind_Parameter_Count := GetProcAddress(DLLHandle, 'sqlite3_bind_parameter_count');
If Not Assigned(@SQLite3_Bind_Parameter_Count) Then exit;
Result := true;
End;
{$ELSE}
DLLHandle := 1;
@SQLite3_Key := @_sqlite3_key;
@SQLite3_Rekey := @_sqlite3_rekey;
@SQLite3_Open := @_sqlite3_open;
@SQLite3_Close := @_sqlite3_close;
@SQLite3_Exec := @_sqlite3_exec;
@SQLite3_LibVersion := @_sqlite3_libversion;
@SQLite3_ErrorString := @_sqlite3_errmsg;
@SQLite3_GetTable := @_sqlite3_get_table;
@SQLite3_FreeTable := @_sqlite3_free_table;
@SQLite3_FreeMem := @_sqlite3_free;
@SQLite3_Complete := @_sqlite3_complete;
@SQLite3_LastInsertRow := @_sqlite3_last_insert_rowid;
@SQLite3_Cancel := @_sqlite3_interrupt;
@SQLite3_BusyTimeout := @_sqlite3_busy_timeout;
@SQLite3_BusyHandler := @_sqlite3_busy_handler;
@SQLite3_Changes := @_sqlite3_changes;
@SQLite3_Prepare := @_sqlite3_prepare;
@SQLite3_Finalize := @_sqlite3_finalize;
@SQLite3_Reset := @_sqlite3_reset;
@SQLite3_Step := @_sqlite3_step;
@SQLite3_Column_blob := @_sqlite3_column_blob;
@SQLite3_Column_bytes := @_sqlite3_column_bytes;
@SQLite3_Column_count := @_sqlite3_column_count;
@SQLite3_Column_decltype := @_sqlite3_column_decltype;
@SQLite3_Column_double := @_sqlite3_column_double;
@SQLite3_Column_int := @_sqlite3_column_int;
@SQLite3_Column_int64 := @_sqlite3_column_int64;
@SQLite3_Column_name := @_sqlite3_column_name;
@SQLite3_Column_text := @_sqlite3_column_text;
@SQLite3_Column_type := @_sqlite3_column_type;
@SQLite3_Bind_Blob := @_sqlite3_bind_blob;
Result := true;
{$ENDIF}
Finally
DebugLeave('TASQLite3DB.LoadLibs');
End;
End;
Procedure TASQLite3DB.ShowError;
Var
Msg: PAnsiChar;
Begin
Msg := SQLite3_ErrorString(DBHandle);
Raise EDatabaseError.Create(Msg);
End;
Function TASQLite3DB.SQLite3_ExecSQL(TheStatement: String; Blobs: TList = Nil): integer;
Var
PF: PAnsiChar;
p: Pointer;
I: integer;
b: integer;
m: TMemoryStream;
Begin
TheStatement := StringReplace(TheStatement, #2, '?', [rfReplaceAll, rfIgnoreCase]);
PF := PAnsiChar(TheStatement);
Repeat
Result := SQLite3_Prepare(DBHandle, PF, -1, p, PF);
If Result = SQLITE_OK Then
Begin
If Assigned(Blobs) Then
Begin
For I := 0 To Blobs.Count - 1 Do
Begin
b := I + 1;
m := TMemoryStream(Blobs.Items[I]);
SQLite3_Bind_Blob(p, b, PChar(m.Memory), m.Size, Nil);
End;
End;
Repeat
Until SQLite3_Step(p) In [SQLITE_DONE, SQLITE_ERROR, SQLITE_MISUSE];
Result := SQLite3_Finalize(p);
If Result <> SQLITE_OK Then ShowError;
End
Else
ShowError;
Until PF^ = #0;
End;
Function TASQLite3DB.SQLite3_PrepareResult(DB: TSQLiteDB; TheStatement: String; FParams: TParams; Sender: TObject): Pointer;
Var
I, tmpi: integer;
t: PAnsiChar;
RV: integer;
// RowIdCol: Integer; // column containing rowid
// RowId: Integer; // current record row id (to be stored in resultset)
colname, coltype: PChar;
tmpcolname: String;
FieldType: TFieldType;
FieldLen: integer;
FieldDec: integer;
bFirst: boolean;
wildcard: integer;
Begin
If Not (Sender Is TASQLite3BaseQuery) Then exit;
With (Sender As TASQLite3BaseQuery) Do
Begin
// if there are blob fields then we need to bind the blob variable
RowId := -1;
RowIdCol := -1;
TheStatement := StringReplace(TheStatement, #2, '?', [rfReplaceAll, rfIgnoreCase]);
bFirst := true;
{$IFDEF ASQLITE_D6PLUS}
If FUtf8 Then
RV := SQLite3_Prepare(DBHandle, PAnsiChar(AnsiToUtf8(TheStatement)), -1, Result, t)
Else
{$ENDIF}
RV := SQLite3_Prepare(DBHandle, PAnsiChar(TheStatement), -1, Result, t);
wildcard := 1;
If Assigned(FParams) Then
Begin
For I := 0 To FParams.Count - 1 Do
Begin
If FParams[I].DataType In [ftBlob, ftGraphic] Then
Begin
SQLite3_Bind_Blob(Result, wildcard, PChar(FParams[I].AsBlob), FParams[I].GetDataSize, Nil);
inc(wildcard);
End;
End;
End;
If RV <> 0 Then ShowError Else
Begin
If bFirst Then
Begin // retrieve metadata on first row
bFirst := false;
If SQLite3_Column_count(Result) > 0 Then FieldDefs.Clear;
For I := 0 To SQLite3_Column_count(Result) - 1 Do
Begin
colname := SQLite3_Column_name(Result, I);
// the second field named "ID", change in "ID_1" (like InterBase)
If (FieldDefs.IndexOf(colname) >= 0) Then
Begin // Mirko
tmpcolname := colname; // Mirko
tmpi := 0; // Mirko
While (FieldDefs.IndexOf(tmpcolname) >= 0) Do
Begin // Mirko
inc(tmpi); // Mirko
tmpcolname := colname + '_' + IntToStr(tmpi); // Mirko
End; // Mirko
colname := PChar(tmpcolname); // Mirko
End; // Mirko
If CompareText(colname, 'rowid') = 0 Then
Begin
RowIdCol := I;
End Else
Begin
coltype := SQLite3_Column_decltype(Result, I);
//SQl: select max(CurID) from Items, sqlite3_column_decltype returns null.. it's probably SQLite bug
// better is to use max(CurID) as something from .... Aducom
If coltype = Nil Then
GetFieldInfo('string', FieldType, FieldLen, FieldDec) //OL
Else
GetFieldInfo(coltype, FieldType, FieldLen, FieldDec);
If TypeLess Then
Begin
FieldType := ftString;
With FieldDefs.AddFieldDef Do
Begin
Name := colname;
DataType := FieldType;
Size := FieldLen;
End;
End Else
Begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -