disqlite3database.pas
来自「DELPHI 访问SQLITE3 数据库的VCL控件」· PAS 代码 · 共 2,333 行 · 第 1/5 页
PAS
2,333 行
i := FStatements.Count - 1;
while i >= 0 do
begin
Stmt := TDISQLite3Statement(FStatements[i]);
Stmt.Active := False;
Stmt.Database := nil;
Dec(i);
end;
Connected := False;
FStatements.Free;
inherited;
end;
procedure TDISQLite3Database.AttachDatabase16(const ADatabaseName: WideString; AAlias: WideString = '');
var
Stmt: TDISQLite3Statement;
begin
CheckActive;
CheckDatabaseName(ADatabaseName);
if IsMemoryDatabaseName(ADatabaseName) and not WideFileExists(ADatabaseName) then
raise EFOpenError.CreateFmt(SFOpenError, [WideExpandFileName(ADatabaseName)]);
if AAlias = '' then
AAlias := WideChangeFileExt(WideExtractFileName(ADatabaseName), '');
Stmt := Prepare16('ATTACH ? AS ?');
try
Stmt.bind_Str16(1, ADatabaseName);
Stmt.bind_Str16(2, AAlias);
Stmt.Step;
finally
Stmt.Free;
end;
end;
function TDISQLite3Database.Changes: Integer;
begin
CheckActive;
Result := sqlite3_changes(FHandle);
end;
function TDISQLite3Database.Check(const AErrorCode: Integer): Integer;
begin
Result := AErrorCode;
if Result <> SQLITE_OK then
sqlite3_raise_exception(Result, FHandle);
end;
procedure TDISQLite3Database.CheckActive;
begin
if not Assigned(FHandle) then
DatabaseError(PResStringRec(@SDatabaseClosed), Self);
end;
procedure TDISQLite3Database.CheckDatabaseName(const ADatabaseName: WideString);
var
l: Integer;
p: PWideChar;
begin
l := Length(ADatabaseName);
if l > 0 then
begin
p := Pointer(ADatabaseName);
repeat
if p^ > WC_SPACE then Exit;
Inc(p); Dec(l);
until l = 0;
end;
DatabaseError(PResStringRec(@SDatabaseNameMissing), Self);
end;
procedure TDISQLite3Database.CheckInactive;
begin
if Assigned(FHandle) then
DatabaseError(PResStringRec(@SDatabaseOpen), Self);
end;
procedure TDISQLite3Database.Close;
begin
SetConnected(False);
end;
procedure TDISQLite3Database.CloseStatements;
var
i: Integer;
Stmt: TDISQLite3Statement;
begin
for i := 0 to FStatements.Count - 1 do
begin
Stmt := TDISQLite3Statement(FStatements[i]);
Stmt.Active := False;
end;
end;
procedure TDISQLite3Database.Commit;
begin
if InTransaction then
begin
if FTransactionCount = 1 then
begin
CheckActive;
Check(sqlite3_exec_with_callback(FHandle, 'COMMIT TRANSACTION;'));
end;
Dec(FTransactionCount);
end;
end;
procedure TDISQLite3Database.DoAfterConnect;
begin
if Assigned(FAfterConnect) then
FAfterConnect(Self);
end;
procedure TDISQLite3Database.DoAfterCreateDatabase;
begin
if Assigned(FAfterCreateDatabase) then
FAfterCreateDatabase(Self);
end;
procedure TDISQLite3Database.DoAfterDisconnect;
begin
if Assigned(FAfterDisconnect) then
FAfterDisconnect(Self);
end;
procedure TDISQLite3Database.DoBeforeCreateDatabase;
begin
if Assigned(FBeforeCreateDatabase) then
FBeforeCreateDatabase(Self);
end;
procedure TDISQLite3Database.DoBeforeConnect;
begin
if Assigned(FBeforeConnect) then
FBeforeConnect(Self);
end;
procedure TDISQLite3Database.DoBeforeDisconnect;
begin
if Assigned(FBeforeDisconnect) then
FBeforeDisconnect(Self);
end;
procedure TDISQLite3Database.DoConnect;
var
s8: AnsiString;
begin
if not Assigned(FHandle) then
begin
CheckDatabaseName(FDatabaseName);
if not IsMemoryDatabaseName(FDatabaseName) and not WideFileExists(FDatabaseName) then
begin
raise EFOpenError.CreateFmt(SFOpenError, [WideExpandFileName(FDatabaseName)]);
end;
s8 := sqlite3_encode_utf8(FDatabaseName);
Check(sqlite3_open(PAnsiChar(s8), @FHandle));
if FPassword <> '' then
Check(sqlite3_key(FHandle, Pointer(FPassword), Length(FPassword)));
end;
end;
procedure TDISQLite3Database.DoDisconnect;
var
h: TDISQLite3StatementHandle;
begin
if Assigned(FHandle) then
begin
CloseStatements;
h := FHandle;
FHandle := nil;
Check(sqlite3_close(h));
end;
end;
procedure TDISQLite3Database.DoInitDatabase;
begin
if Assigned(FInitDatabase) then
FInitDatabase(Self);
end;
function TDISQLite3Database.GetAutoVacuum: Boolean;
begin
CheckActive;
Check(sqlite3_get_auto_vacuum(FHandle, Result))
end;
procedure TDISQLite3Database.SetAutoVacuum(const AValue: Boolean);
begin
CheckActive;
Check(sqlite3_set_auto_vacuum(FHandle, AValue));
end;
function TDISQLite3Database.GetCacheSize: Integer;
begin
CheckActive;
Check(sqlite3_get_cache_size(FHandle, Result));
end;
procedure TDISQLite3Database.SetCacheSize(const AValue: Integer);
begin
CheckActive;
Check(sqlite3_pragma_set_cache_size(FHandle, AValue));
end;
procedure TDISQLite3Database.SetCaseSensitiveLike(const AValue: Boolean);
begin
CheckActive;
Check(sqlite3_pragma_set_case_sensitive_like(FHandle, AValue));
end;
function TDISQLite3Database.GetConnected: Boolean;
begin
Result := Assigned(FHandle);
end;
function TDISQLite3Database.GetCountChanges: Boolean;
begin
CheckActive;
Check(sqlite3_pragma_get_count_changes(FHandle, Result))
end;
procedure TDISQLite3Database.SetCountChanges(const AValue: Boolean);
begin
CheckActive;
Check(sqlite3_pragma_set_count_changes(FHandle, AValue));
end;
function TDISQLite3Database.GetDefaultCacheSize: Integer;
begin
CheckActive;
Check(sqlite3_get_default_cache_size(FHandle, Result))
end;
procedure TDISQLite3Database.SetDefaultCacheSize(const AValue: Integer);
begin
CheckActive;
Check(sqlite3_set_default_cache_size(FHandle, AValue));
end;
function TDISQLite3Database.GetEmptyResultCallbacks: Boolean;
begin
CheckActive;
Check(sqlite3_get_empty_result_callbacks(FHandle, Result))
end;
procedure TDISQLite3Database.SetEmptyResultCallbacks(const Value: Boolean);
begin
end;
function TDISQLite3Database.GetEncoding: WideString;
{$IFDEF SQLITE_OMIT_UTF16}
var
s8: AnsiString;
{$ENDIF SQLITE_OMIT_UTF16}
begin
CheckActive;
{$IFDEF SQLITE_OMIT_UTF16}
Check(sqlite3_pragma_get_encoding(FHandle, s8));
Result := sqlite3_decode_utf8(s8);
{$ELSE SQLITE_OMIT_UTF16}
Check(sqlite3_pragma_get_encoding16(FHandle, Result));
{$ENDIF SQLITE_OMIT_UTF16}
end;
procedure TDISQLite3Database.SetEncoding(const AValue: WideString);
begin
CheckActive;
{$IFDEF SQLITE_OMIT_UTF16}
Check(sqlite3_set_encoding(FHandle, sqlite3_encode_utf8(AValue)));
{$ELSE SQLITE_OMIT_UTF16}
Check(sqlite3_set_encoding16(FHandle, AValue));
{$ENDIF SQLITE_OMIT_UTF16}
end;
function TDISQLite3Database.GetInTransaction: Boolean;
begin
Result := FTransactionCount > 0;
end;
function TDISQLite3Database.GetStatementClass: TDISQLite3StatementClass;
begin
Result := TDISQLite3Statement;
end;
function TDISQLite3Database.GetSQLiteVersion: WideString;
begin
Result := sqlite3_libversion;
end;
procedure TDISQLite3Database.CreateDatabase;
var
s8: AnsiString;
begin
CheckInactive;
CheckDatabaseName(FDatabaseName);
if WideFileExists(FDatabaseName) and not WideDeleteFile(FDatabaseName) then
raise EFCreateError.CreateFmt(SFCreateError, [WideExpandFileName(FDatabaseName)]);
DoBeforeConnect;
DoBeforeCreateDatabase;
s8 := sqlite3_encode_utf8(FDatabaseName);
Check(sqlite3_open(PAnsiChar(s8), @FHandle));
if FPassword <> '' then
Check(sqlite3_key(FHandle, Pointer(FPassword), Length(FPassword)));
DoInitDatabase;
DoAfterCreateDatabase;
DoAfterConnect;
end;
procedure TDISQLite3Database.Execute(const ASQL: AnsiString);
begin
CheckActive;
Check(sqlite3_exec_with_callback(FHandle, ASQL));
end;
procedure TDISQLite3Database.Execute16(const ASQL: WideString);
begin
CheckActive;
Check(sqlite3_exec_with_callback(FHandle, sqlite3_encode_utf8(ASQL)));
end;
function TDISQLite3Database.IntegrityCheck: Integer;
begin
CheckActive;
Result := sqlite3_integrity_check(FHandle);
end;
procedure TDISQLite3Database.Interrupt;
begin
CheckActive;
sqlite3_interrupt(FHandle);
end;
function TDISQLite3Database.IsMemoryDatabaseName(const ADatabaseName: WideString): Boolean;
begin
Result := (Length(ADatabaseName) = 8) and
(ADatabaseName[1] = ':') and
((ADatabaseName[2] = 'M') or (ADatabaseName[2] = 'm')) and
((ADatabaseName[3] = 'E') or (ADatabaseName[3] = 'e')) and
((ADatabaseName[4] = 'M') or (ADatabaseName[4] = 'm')) and
((ADatabaseName[5] = 'O') or (ADatabaseName[5] = 'o')) and
((ADatabaseName[6] = 'R') or (ADatabaseName[6] = 'r')) and
((ADatabaseName[7] = 'Y') or (ADatabaseName[7] = 'y')) and
(ADatabaseName[8] = ':');
end;
function TDISQLite3Database.LastInsertRowID: Int64;
begin
CheckActive;
Result := sqlite3_last_insert_rowid(FHandle);
end;
procedure TDISQLite3Database.Loaded;
begin
inherited;
try
if FStreamedConnected then
SetConnected(True);
except
if csDesigning in ComponentState then
{$IFDEF COMPILER_6_UP}
if Assigned(Classes.ApplicationHandleException) then
Classes.ApplicationHandleException(ExceptObject)
else
{$ENDIF}
ShowException(ExceptObject, ExceptAddr)
else
raise;
end;
end;
procedure TDISQLite3Database.Open;
begin
SetConnected(True);
end;
function TDISQLite3Database.Prepare(const ASQL8: AnsiString): TDISQLite3Statement;
begin
Result := GetStatementClass.Create;
Result.Database := Self;
Result.SQL8 := ASQL8;
Result.Open;
end;
function TDISQLite3Database.Prepare16(const ASQL16: WideString): TDISQLite3Statement;
begin
Result := GetStatementClass.Create;
Result.Database := Self;
Result.SQL16 := ASQL16;
Result.Open;
end;
procedure TDISQLite3Database.RegisterStatement(const AStatement: TDISQLite3Statement);
begin
if Assigned(AStatement) then
FStatements.Add(AStatement);
end;
procedure TDISQLite3Database.ReKey(const ANewPassword: AnsiString);
begin
CheckActive;
Check(sqlite3_rekey(FHandle, Pointer(ANewPassword), Length(ANewPassword)));
FPassword := ANewPassword;
end;
procedure TDISQLite3Database.Rollback;
begin
if InTransaction then
begin
if FTransactionCount = 1 then
begin
CheckActive;
Check(sqlite3_exec_with_callback(FHandle, 'ROLLBACK TRANSACTION;'));
end;
Dec(FTransactionCount);
end;
end;
procedure TDISQLite3Database.SetConnected(const AValue: Boolean);
begin
if (csReading in ComponentState) and AValue then
FStreamedConnected := True
else
if AValue <> GetConnected then
if AValue then
begin
DoBeforeConnect;
DoConnect;
DoInitDatabase;
DoAfterConnect;
end
else
begin
DoBeforeDisconnect;
DoDisconnect;
DoAfterDisconnect;
end;
end;
procedure TDISQLite3Database.SetDatabaseName(const AValue: WideString);
begin
CheckInactive;
FDatabaseName := AValue;
end;
procedure TDISQLite3Database.SetPassword(const AValue: AnsiString);
begin
if Connected then
begin
Check(sqlite3_key(FHandle, Pointer(AValue), Length(AValue)));
end;
FPassword := AValue;
end;
procedure TDISQLite3D
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?