SQLITE_STATIC -> SQLITE_TRANSIENT in BindBlob()
This commit is contained in:
1760
Source/SQLite3.pas
1760
Source/SQLite3.pas
File diff suppressed because it is too large
Load Diff
@@ -1,96 +1,96 @@
|
|||||||
{
|
{
|
||||||
SQLite for Delphi and FreePascal/Lazarus
|
SQLite for Delphi and FreePascal/Lazarus
|
||||||
|
|
||||||
Copyright 2010 Yury Plashenkov <plashenkov@gmail.com>
|
Copyright 2010-2012 Yury Plashenkov <plashenkov@gmail.com>
|
||||||
http://www.indasoftware.com/sqlite/
|
http://www.indasoftware.com/sqlite/
|
||||||
|
|
||||||
SQLite is a software library that implements a self-contained, serverless,
|
SQLite is a software library that implements a self-contained, serverless,
|
||||||
zero-configuration, transactional SQL database engine. The source code for
|
zero-configuration, transactional SQL database engine. The source code for
|
||||||
SQLite is in the public domain and is thus free for use for any purpose,
|
SQLite is in the public domain and is thus free for use for any purpose,
|
||||||
commercial or private. SQLite is the most widely deployed SQL database engine
|
commercial or private. SQLite is the most widely deployed SQL database engine
|
||||||
in the world.
|
in the world.
|
||||||
|
|
||||||
This package contains complete SQLite3 API translation for Delphi and
|
This package contains complete SQLite3 API translation for Delphi and
|
||||||
FreePascal, as well as a simple Unicode-enabled object wrapper to simplify
|
FreePascal, as well as a simple Unicode-enabled object wrapper to simplify
|
||||||
the use of this database engine.
|
the use of this database engine.
|
||||||
|
|
||||||
The contents of this file are used with permission, subject to the Mozilla
|
The contents of this file are used with permission, subject to the Mozilla
|
||||||
Public License Version 1.1 (the "License"); you may not use this file except
|
Public License Version 1.1 (the "License"); you may not use this file except
|
||||||
in compliance with the License. You may obtain a copy of the License at
|
in compliance with the License. You may obtain a copy of the License at
|
||||||
http://www.mozilla.org/MPL/MPL-1.1.html
|
http://www.mozilla.org/MPL/MPL-1.1.html
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||||
the specific language governing rights and limitations under the License.
|
the specific language governing rights and limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Miscellaneous utility functions
|
Miscellaneous utility functions
|
||||||
}
|
}
|
||||||
unit SQLite3Utils;
|
unit SQLite3Utils;
|
||||||
|
|
||||||
{$IFDEF FPC}
|
{$IFDEF FPC}
|
||||||
{$MODE DELPHI}
|
{$MODE DELPHI}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
{$WARN SYMBOL_DEPRECATED OFF}
|
{$WARN SYMBOL_DEPRECATED OFF}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
function StrToUTF8(const S: WideString): AnsiString;
|
function StrToUTF8(const S: WideString): AnsiString;
|
||||||
function UTF8ToStr(const S: PAnsiChar; const Len: Integer = -1): WideString;
|
function UTF8ToStr(const S: PAnsiChar; const Len: Integer = -1): WideString;
|
||||||
function QuotedStr(const S: WideString): WideString;
|
function QuotedStr(const S: WideString): WideString;
|
||||||
function FloatToSQLStr(Value: Extended): WideString;
|
function FloatToSQLStr(Value: Extended): WideString;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses SysUtils;
|
uses SysUtils;
|
||||||
|
|
||||||
function StrToUTF8(const S: WideString): AnsiString;
|
function StrToUTF8(const S: WideString): AnsiString;
|
||||||
begin
|
begin
|
||||||
Result := UTF8Encode(S);
|
Result := UTF8Encode(S);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function UTF8ToStr(const S: PAnsiChar; const Len: Integer): WideString;
|
function UTF8ToStr(const S: PAnsiChar; const Len: Integer): WideString;
|
||||||
var
|
var
|
||||||
UTF8Str: AnsiString;
|
UTF8Str: AnsiString;
|
||||||
begin
|
begin
|
||||||
if Len < 0 then
|
if Len < 0 then
|
||||||
begin
|
begin
|
||||||
Result := UTF8Decode(S);
|
Result := UTF8Decode(S);
|
||||||
end
|
end
|
||||||
else if Len > 0 then
|
else if Len > 0 then
|
||||||
begin
|
begin
|
||||||
SetLength(UTF8Str, Len);
|
SetLength(UTF8Str, Len);
|
||||||
Move(S^, UTF8Str[1], Len);
|
Move(S^, UTF8Str[1], Len);
|
||||||
Result := UTF8Decode(UTF8Str);
|
Result := UTF8Decode(UTF8Str);
|
||||||
end
|
end
|
||||||
else Result := '';
|
else Result := '';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function QuotedStr(const S: WideString): WideString;
|
function QuotedStr(const S: WideString): WideString;
|
||||||
const
|
const
|
||||||
Quote = #39;
|
Quote = #39;
|
||||||
var
|
var
|
||||||
I: Integer;
|
I: Integer;
|
||||||
begin
|
begin
|
||||||
Result := S;
|
Result := S;
|
||||||
for I := Length(Result) downto 1 do
|
for I := Length(Result) downto 1 do
|
||||||
if Result[I] = Quote then Insert(Quote, Result, I);
|
if Result[I] = Quote then Insert(Quote, Result, I);
|
||||||
Result := Quote + Result + Quote;
|
Result := Quote + Result + Quote;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function FloatToSQLStr(Value: Extended): WideString;
|
function FloatToSQLStr(Value: Extended): WideString;
|
||||||
var
|
var
|
||||||
SaveSeparator: Char;
|
SaveSeparator: Char;
|
||||||
begin
|
begin
|
||||||
SaveSeparator := DecimalSeparator;
|
SaveSeparator := DecimalSeparator;
|
||||||
DecimalSeparator := '.';
|
DecimalSeparator := '.';
|
||||||
try
|
try
|
||||||
Result := FloatToStr(Value);
|
Result := FloatToStr(Value);
|
||||||
finally
|
finally
|
||||||
DecimalSeparator := SaveSeparator;
|
DecimalSeparator := SaveSeparator;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|||||||
@@ -1,477 +1,477 @@
|
|||||||
{
|
{
|
||||||
SQLite for Delphi and FreePascal/Lazarus
|
SQLite for Delphi and FreePascal/Lazarus
|
||||||
|
|
||||||
Copyright 2010 Yury Plashenkov <plashenkov@gmail.com>
|
Copyright 2010-2012 Yury Plashenkov <plashenkov@gmail.com>
|
||||||
http://www.indasoftware.com/sqlite/
|
http://www.indasoftware.com/sqlite/
|
||||||
|
|
||||||
SQLite is a software library that implements a self-contained, serverless,
|
SQLite is a software library that implements a self-contained, serverless,
|
||||||
zero-configuration, transactional SQL database engine. The source code for
|
zero-configuration, transactional SQL database engine. The source code for
|
||||||
SQLite is in the public domain and is thus free for use for any purpose,
|
SQLite is in the public domain and is thus free for use for any purpose,
|
||||||
commercial or private. SQLite is the most widely deployed SQL database engine
|
commercial or private. SQLite is the most widely deployed SQL database engine
|
||||||
in the world.
|
in the world.
|
||||||
|
|
||||||
This package contains complete SQLite3 API translation for Delphi and
|
This package contains complete SQLite3 API translation for Delphi and
|
||||||
FreePascal, as well as a simple Unicode-enabled object wrapper to simplify
|
FreePascal, as well as a simple Unicode-enabled object wrapper to simplify
|
||||||
the use of this database engine.
|
the use of this database engine.
|
||||||
|
|
||||||
The contents of this file are used with permission, subject to the Mozilla
|
The contents of this file are used with permission, subject to the Mozilla
|
||||||
Public License Version 1.1 (the "License"); you may not use this file except
|
Public License Version 1.1 (the "License"); you may not use this file except
|
||||||
in compliance with the License. You may obtain a copy of the License at
|
in compliance with the License. You may obtain a copy of the License at
|
||||||
http://www.mozilla.org/MPL/MPL-1.1.html
|
http://www.mozilla.org/MPL/MPL-1.1.html
|
||||||
|
|
||||||
Software distributed under the License is distributed on an "AS IS" basis,
|
Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
|
||||||
the specific language governing rights and limitations under the License.
|
the specific language governing rights and limitations under the License.
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Simple object wrapper over SQLite3 API
|
Simple object wrapper over SQLite3 API
|
||||||
}
|
}
|
||||||
unit SQLite3Wrap;
|
unit SQLite3Wrap;
|
||||||
|
|
||||||
{$IFDEF FPC}
|
{$IFDEF FPC}
|
||||||
{$MODE DELPHI}
|
{$MODE DELPHI}
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
SysUtils, Classes, SQLite3;
|
SysUtils, Classes, SQLite3;
|
||||||
|
|
||||||
type
|
type
|
||||||
ESQLite3Error = class(Exception);
|
ESQLite3Error = class(Exception);
|
||||||
|
|
||||||
TSQLite3Statement = class;
|
TSQLite3Statement = class;
|
||||||
TSQLite3BlobHandler = class;
|
TSQLite3BlobHandler = class;
|
||||||
|
|
||||||
{ TSQLite3Database class }
|
{ TSQLite3Database class }
|
||||||
|
|
||||||
TSQLite3Database = class(TObject)
|
TSQLite3Database = class(TObject)
|
||||||
private
|
private
|
||||||
FHandle: PSQLite3;
|
FHandle: PSQLite3;
|
||||||
FStatementList: TList;
|
FStatementList: TList;
|
||||||
FBlobHandlerList: TList;
|
FBlobHandlerList: TList;
|
||||||
FTransactionOpen: Boolean;
|
FTransactionOpen: Boolean;
|
||||||
procedure Check(const ErrCode: Integer);
|
procedure Check(const ErrCode: Integer);
|
||||||
procedure CheckHandle;
|
procedure CheckHandle;
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
procedure Open(const FileName: WideString);
|
procedure Open(const FileName: WideString);
|
||||||
procedure Close;
|
procedure Close;
|
||||||
|
|
||||||
procedure Execute(const SQL: WideString);
|
procedure Execute(const SQL: WideString);
|
||||||
function LastInsertRowID: Int64;
|
function LastInsertRowID: Int64;
|
||||||
function Prepare(const SQL: WideString): TSQLite3Statement;
|
function Prepare(const SQL: WideString): TSQLite3Statement;
|
||||||
function BlobOpen(const Table, Column: WideString; const RowID: Int64; const WriteAccess: Boolean = True): TSQLite3BlobHandler;
|
function BlobOpen(const Table, Column: WideString; const RowID: Int64; const WriteAccess: Boolean = True): TSQLite3BlobHandler;
|
||||||
|
|
||||||
procedure BeginTransaction;
|
procedure BeginTransaction;
|
||||||
procedure Commit;
|
procedure Commit;
|
||||||
procedure Rollback;
|
procedure Rollback;
|
||||||
|
|
||||||
property Handle: PSQLite3 read FHandle;
|
property Handle: PSQLite3 read FHandle;
|
||||||
property TransactionOpen: Boolean read FTransactionOpen;
|
property TransactionOpen: Boolean read FTransactionOpen;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TSQLite3Statement class }
|
{ TSQLite3Statement class }
|
||||||
|
|
||||||
TSQLite3Statement = class(TObject)
|
TSQLite3Statement = class(TObject)
|
||||||
private
|
private
|
||||||
FHandle: PSQLite3Stmt;
|
FHandle: PSQLite3Stmt;
|
||||||
FOwnerDatabase: TSQLite3Database;
|
FOwnerDatabase: TSQLite3Database;
|
||||||
function ParamIndexByName(const ParamName: WideString): Integer;
|
function ParamIndexByName(const ParamName: WideString): Integer;
|
||||||
public
|
public
|
||||||
constructor Create(OwnerDatabase: TSQLite3Database; const SQL: WideString);
|
constructor Create(OwnerDatabase: TSQLite3Database; const SQL: WideString);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
procedure BindInt(const ParamIndex: Integer; const Value: Integer); overload;
|
procedure BindInt(const ParamIndex: Integer; const Value: Integer); overload;
|
||||||
procedure BindInt64(const ParamIndex: Integer; const Value: Int64); overload;
|
procedure BindInt64(const ParamIndex: Integer; const Value: Int64); overload;
|
||||||
procedure BindDouble(const ParamIndex: Integer; const Value: Double); overload;
|
procedure BindDouble(const ParamIndex: Integer; const Value: Double); overload;
|
||||||
procedure BindText(const ParamIndex: Integer; const Value: WideString); overload;
|
procedure BindText(const ParamIndex: Integer; const Value: WideString); overload;
|
||||||
procedure BindNull(const ParamIndex: Integer); overload;
|
procedure BindNull(const ParamIndex: Integer); overload;
|
||||||
procedure BindBlob(const ParamIndex: Integer; Data: Pointer; const Size: Integer); overload;
|
procedure BindBlob(const ParamIndex: Integer; Data: Pointer; const Size: Integer); overload;
|
||||||
procedure BindZeroBlob(const ParamIndex: Integer; const Size: Integer); overload;
|
procedure BindZeroBlob(const ParamIndex: Integer; const Size: Integer); overload;
|
||||||
procedure BindInt(const ParamName: WideString; const Value: Integer); overload;
|
procedure BindInt(const ParamName: WideString; const Value: Integer); overload;
|
||||||
procedure BindInt64(const ParamName: WideString; const Value: Int64); overload;
|
procedure BindInt64(const ParamName: WideString; const Value: Int64); overload;
|
||||||
procedure BindDouble(const ParamName: WideString; const Value: Double); overload;
|
procedure BindDouble(const ParamName: WideString; const Value: Double); overload;
|
||||||
procedure BindText(const ParamName: WideString; const Value: WideString); overload;
|
procedure BindText(const ParamName: WideString; const Value: WideString); overload;
|
||||||
procedure BindNull(const ParamName: WideString); overload;
|
procedure BindNull(const ParamName: WideString); overload;
|
||||||
procedure BindBlob(const ParamName: WideString; Data: Pointer; const Size: Integer); overload;
|
procedure BindBlob(const ParamName: WideString; Data: Pointer; const Size: Integer); overload;
|
||||||
procedure BindZeroBlob(const ParamName: WideString; const Size: Integer); overload;
|
procedure BindZeroBlob(const ParamName: WideString; const Size: Integer); overload;
|
||||||
procedure ClearBindings;
|
procedure ClearBindings;
|
||||||
|
|
||||||
function Step: Integer;
|
function Step: Integer;
|
||||||
|
|
||||||
function ColumnCount: Integer;
|
function ColumnCount: Integer;
|
||||||
function ColumnName(const ColumnIndex: Integer): WideString;
|
function ColumnName(const ColumnIndex: Integer): WideString;
|
||||||
function ColumnType(const ColumnIndex: Integer): Integer;
|
function ColumnType(const ColumnIndex: Integer): Integer;
|
||||||
function ColumnInt(const ColumnIndex: Integer): Integer;
|
function ColumnInt(const ColumnIndex: Integer): Integer;
|
||||||
function ColumnInt64(const ColumnIndex: Integer): Int64;
|
function ColumnInt64(const ColumnIndex: Integer): Int64;
|
||||||
function ColumnDouble(const ColumnIndex: Integer): Double;
|
function ColumnDouble(const ColumnIndex: Integer): Double;
|
||||||
function ColumnText(const ColumnIndex: Integer): WideString;
|
function ColumnText(const ColumnIndex: Integer): WideString;
|
||||||
function ColumnBlob(const ColumnIndex: Integer): Pointer;
|
function ColumnBlob(const ColumnIndex: Integer): Pointer;
|
||||||
function ColumnBytes(const ColumnIndex: Integer): Integer;
|
function ColumnBytes(const ColumnIndex: Integer): Integer;
|
||||||
|
|
||||||
procedure Reset;
|
procedure Reset;
|
||||||
procedure StepAndReset;
|
procedure StepAndReset;
|
||||||
|
|
||||||
property Handle: PSQLite3Stmt read FHandle;
|
property Handle: PSQLite3Stmt read FHandle;
|
||||||
property OwnerDatabase: TSQLite3Database read FOwnerDatabase;
|
property OwnerDatabase: TSQLite3Database read FOwnerDatabase;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TSQLite3BlobHandler class }
|
{ TSQLite3BlobHandler class }
|
||||||
|
|
||||||
TSQLite3BlobHandler = class(TObject)
|
TSQLite3BlobHandler = class(TObject)
|
||||||
private
|
private
|
||||||
FHandle: PSQLite3Blob;
|
FHandle: PSQLite3Blob;
|
||||||
FOwnerDatabase: TSQLite3Database;
|
FOwnerDatabase: TSQLite3Database;
|
||||||
public
|
public
|
||||||
constructor Create(OwnerDatabase: TSQLite3Database; const Table, Column: WideString; const RowID: Int64; const WriteAccess: Boolean = True);
|
constructor Create(OwnerDatabase: TSQLite3Database; const Table, Column: WideString; const RowID: Int64; const WriteAccess: Boolean = True);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
|
|
||||||
function Bytes: Integer;
|
function Bytes: Integer;
|
||||||
procedure Read(Buffer: Pointer; const Size, Offset: Integer);
|
procedure Read(Buffer: Pointer; const Size, Offset: Integer);
|
||||||
procedure Write(Buffer: Pointer; const Size, Offset: Integer);
|
procedure Write(Buffer: Pointer; const Size, Offset: Integer);
|
||||||
|
|
||||||
property Handle: PSQLite3Blob read FHandle;
|
property Handle: PSQLite3Blob read FHandle;
|
||||||
property OwnerDatabase: TSQLite3Database read FOwnerDatabase;
|
property OwnerDatabase: TSQLite3Database read FOwnerDatabase;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses SQLite3Utils;
|
uses SQLite3Utils;
|
||||||
|
|
||||||
resourcestring
|
resourcestring
|
||||||
SErrorMessage = 'SQLite3 error: %s';
|
SErrorMessage = 'SQLite3 error: %s';
|
||||||
SDatabaseNotConnected = 'SQLite3 error: database is not connected.';
|
SDatabaseNotConnected = 'SQLite3 error: database is not connected.';
|
||||||
STransactionAlreadyOpen = 'Transaction is already opened.';
|
STransactionAlreadyOpen = 'Transaction is already opened.';
|
||||||
SNoTransactionOpen = 'No transaction is open';
|
SNoTransactionOpen = 'No transaction is open';
|
||||||
|
|
||||||
{ TSQLite3Database }
|
{ TSQLite3Database }
|
||||||
|
|
||||||
procedure TSQLite3Database.BeginTransaction;
|
procedure TSQLite3Database.BeginTransaction;
|
||||||
begin
|
begin
|
||||||
if not FTransactionOpen then
|
if not FTransactionOpen then
|
||||||
begin
|
begin
|
||||||
Execute('BEGIN TRANSACTION;');
|
Execute('BEGIN TRANSACTION;');
|
||||||
FTransactionOpen := True;
|
FTransactionOpen := True;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise ESQLite3Error.Create(STransactionAlreadyOpen);
|
raise ESQLite3Error.Create(STransactionAlreadyOpen);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Database.BlobOpen(const Table, Column: WideString;
|
function TSQLite3Database.BlobOpen(const Table, Column: WideString;
|
||||||
const RowID: Int64; const WriteAccess: Boolean): TSQLite3BlobHandler;
|
const RowID: Int64; const WriteAccess: Boolean): TSQLite3BlobHandler;
|
||||||
begin
|
begin
|
||||||
Result := TSQLite3BlobHandler.Create(Self, Table, Column, RowID, WriteAccess);
|
Result := TSQLite3BlobHandler.Create(Self, Table, Column, RowID, WriteAccess);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Database.Check(const ErrCode: Integer);
|
procedure TSQLite3Database.Check(const ErrCode: Integer);
|
||||||
begin
|
begin
|
||||||
if ErrCode <> SQLITE_OK then
|
if ErrCode <> SQLITE_OK then
|
||||||
raise ESQLite3Error.CreateFmt(SErrorMessage, [UTF8ToStr(sqlite3_errmsg(FHandle))]);
|
raise ESQLite3Error.CreateFmt(SErrorMessage, [UTF8ToStr(sqlite3_errmsg(FHandle))]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Database.CheckHandle;
|
procedure TSQLite3Database.CheckHandle;
|
||||||
begin
|
begin
|
||||||
if FHandle = nil then
|
if FHandle = nil then
|
||||||
raise ESQLite3Error.Create(SDatabaseNotConnected);
|
raise ESQLite3Error.Create(SDatabaseNotConnected);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Database.Close;
|
procedure TSQLite3Database.Close;
|
||||||
var
|
var
|
||||||
I: Integer;
|
I: Integer;
|
||||||
begin
|
begin
|
||||||
if FHandle <> nil then
|
if FHandle <> nil then
|
||||||
begin
|
begin
|
||||||
if FTransactionOpen then
|
if FTransactionOpen then
|
||||||
Rollback;
|
Rollback;
|
||||||
// Delete all statements
|
// Delete all statements
|
||||||
for I := FStatementList.Count - 1 downto 0 do
|
for I := FStatementList.Count - 1 downto 0 do
|
||||||
TSQLite3Statement(FStatementList[I]).Free;
|
TSQLite3Statement(FStatementList[I]).Free;
|
||||||
// Delete all blob handlers
|
// Delete all blob handlers
|
||||||
for I := FBlobHandlerList.Count - 1 downto 0 do
|
for I := FBlobHandlerList.Count - 1 downto 0 do
|
||||||
TSQLite3BlobHandler(FBlobHandlerList[I]).Free;
|
TSQLite3BlobHandler(FBlobHandlerList[I]).Free;
|
||||||
sqlite3_close(FHandle);
|
sqlite3_close(FHandle);
|
||||||
FHandle := nil;
|
FHandle := nil;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Database.Commit;
|
procedure TSQLite3Database.Commit;
|
||||||
begin
|
begin
|
||||||
if FTransactionOpen then
|
if FTransactionOpen then
|
||||||
begin
|
begin
|
||||||
Execute('COMMIT;');
|
Execute('COMMIT;');
|
||||||
FTransactionOpen := False;
|
FTransactionOpen := False;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise ESQLite3Error.Create(SNoTransactionOpen);
|
raise ESQLite3Error.Create(SNoTransactionOpen);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TSQLite3Database.Create;
|
constructor TSQLite3Database.Create;
|
||||||
begin
|
begin
|
||||||
FHandle := nil;
|
FHandle := nil;
|
||||||
FStatementList := TList.Create;
|
FStatementList := TList.Create;
|
||||||
FBlobHandlerList := TList.Create;
|
FBlobHandlerList := TList.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TSQLite3Database.Destroy;
|
destructor TSQLite3Database.Destroy;
|
||||||
begin
|
begin
|
||||||
Close;
|
Close;
|
||||||
FBlobHandlerList.Free;
|
FBlobHandlerList.Free;
|
||||||
FStatementList.Free;
|
FStatementList.Free;
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Database.Execute(const SQL: WideString);
|
procedure TSQLite3Database.Execute(const SQL: WideString);
|
||||||
begin
|
begin
|
||||||
CheckHandle;
|
CheckHandle;
|
||||||
Check(sqlite3_exec(FHandle, PAnsiChar(StrToUTF8(SQL)), nil, nil, nil));
|
Check(sqlite3_exec(FHandle, PAnsiChar(StrToUTF8(SQL)), nil, nil, nil));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Database.LastInsertRowID: Int64;
|
function TSQLite3Database.LastInsertRowID: Int64;
|
||||||
begin
|
begin
|
||||||
CheckHandle;
|
CheckHandle;
|
||||||
Result := sqlite3_last_insert_rowid(FHandle);
|
Result := sqlite3_last_insert_rowid(FHandle);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Database.Open(const FileName: WideString);
|
procedure TSQLite3Database.Open(const FileName: WideString);
|
||||||
begin
|
begin
|
||||||
Close;
|
Close;
|
||||||
Check(sqlite3_open(PAnsiChar(StrToUTF8(FileName)), FHandle));
|
Check(sqlite3_open(PAnsiChar(StrToUTF8(FileName)), FHandle));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Database.Prepare(const SQL: WideString): TSQLite3Statement;
|
function TSQLite3Database.Prepare(const SQL: WideString): TSQLite3Statement;
|
||||||
begin
|
begin
|
||||||
Result := TSQLite3Statement.Create(Self, SQL);
|
Result := TSQLite3Statement.Create(Self, SQL);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Database.Rollback;
|
procedure TSQLite3Database.Rollback;
|
||||||
begin
|
begin
|
||||||
if FTransactionOpen then
|
if FTransactionOpen then
|
||||||
begin
|
begin
|
||||||
Execute('ROLLBACK;');
|
Execute('ROLLBACK;');
|
||||||
FTransactionOpen := False;
|
FTransactionOpen := False;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise ESQLite3Error.Create(SNoTransactionOpen);
|
raise ESQLite3Error.Create(SNoTransactionOpen);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TSQLite3Statement }
|
{ TSQLite3Statement }
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindBlob(const ParamIndex: Integer; Data: Pointer;
|
procedure TSQLite3Statement.BindBlob(const ParamIndex: Integer; Data: Pointer;
|
||||||
const Size: Integer);
|
const Size: Integer);
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.Check(sqlite3_bind_blob(FHandle, ParamIndex, Data, Size, SQLITE_STATIC));
|
FOwnerDatabase.Check(sqlite3_bind_blob(FHandle, ParamIndex, Data, Size, SQLITE_TRANSIENT));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindDouble(const ParamIndex: Integer;
|
procedure TSQLite3Statement.BindDouble(const ParamIndex: Integer;
|
||||||
const Value: Double);
|
const Value: Double);
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.Check(sqlite3_bind_double(FHandle, ParamIndex, Value));
|
FOwnerDatabase.Check(sqlite3_bind_double(FHandle, ParamIndex, Value));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindInt(const ParamIndex, Value: Integer);
|
procedure TSQLite3Statement.BindInt(const ParamIndex, Value: Integer);
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.Check(sqlite3_bind_int(FHandle, ParamIndex, Value));
|
FOwnerDatabase.Check(sqlite3_bind_int(FHandle, ParamIndex, Value));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindInt64(const ParamIndex: Integer;
|
procedure TSQLite3Statement.BindInt64(const ParamIndex: Integer;
|
||||||
const Value: Int64);
|
const Value: Int64);
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.Check(sqlite3_bind_int64(FHandle, ParamIndex, Value));
|
FOwnerDatabase.Check(sqlite3_bind_int64(FHandle, ParamIndex, Value));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindNull(const ParamIndex: Integer);
|
procedure TSQLite3Statement.BindNull(const ParamIndex: Integer);
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.Check(sqlite3_bind_null(FHandle, ParamIndex));
|
FOwnerDatabase.Check(sqlite3_bind_null(FHandle, ParamIndex));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindText(const ParamIndex: Integer;
|
procedure TSQLite3Statement.BindText(const ParamIndex: Integer;
|
||||||
const Value: WideString);
|
const Value: WideString);
|
||||||
var
|
var
|
||||||
S: AnsiString; { UTF-8 string }
|
S: AnsiString; { UTF-8 string }
|
||||||
begin
|
begin
|
||||||
S := StrToUTF8(Value);
|
S := StrToUTF8(Value);
|
||||||
FOwnerDatabase.Check(
|
FOwnerDatabase.Check(
|
||||||
sqlite3_bind_text(FHandle, ParamIndex, PAnsiChar(S), Length(S), SQLITE_TRANSIENT)
|
sqlite3_bind_text(FHandle, ParamIndex, PAnsiChar(S), Length(S), SQLITE_TRANSIENT)
|
||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindZeroBlob(const ParamIndex, Size: Integer);
|
procedure TSQLite3Statement.BindZeroBlob(const ParamIndex, Size: Integer);
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.Check(sqlite3_bind_zeroblob(FHandle, ParamIndex, Size));
|
FOwnerDatabase.Check(sqlite3_bind_zeroblob(FHandle, ParamIndex, Size));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.ClearBindings;
|
procedure TSQLite3Statement.ClearBindings;
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.Check(sqlite3_clear_bindings(FHandle));
|
FOwnerDatabase.Check(sqlite3_clear_bindings(FHandle));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.ColumnBlob(const ColumnIndex: Integer): Pointer;
|
function TSQLite3Statement.ColumnBlob(const ColumnIndex: Integer): Pointer;
|
||||||
begin
|
begin
|
||||||
Result := sqlite3_column_blob(FHandle, ColumnIndex);
|
Result := sqlite3_column_blob(FHandle, ColumnIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.ColumnBytes(const ColumnIndex: Integer): Integer;
|
function TSQLite3Statement.ColumnBytes(const ColumnIndex: Integer): Integer;
|
||||||
begin
|
begin
|
||||||
Result := sqlite3_column_bytes(FHandle, ColumnIndex);
|
Result := sqlite3_column_bytes(FHandle, ColumnIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.ColumnCount: Integer;
|
function TSQLite3Statement.ColumnCount: Integer;
|
||||||
begin
|
begin
|
||||||
Result := sqlite3_column_count(FHandle);
|
Result := sqlite3_column_count(FHandle);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.ColumnDouble(const ColumnIndex: Integer): Double;
|
function TSQLite3Statement.ColumnDouble(const ColumnIndex: Integer): Double;
|
||||||
begin
|
begin
|
||||||
Result := sqlite3_column_double(FHandle, ColumnIndex);
|
Result := sqlite3_column_double(FHandle, ColumnIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.ColumnInt(const ColumnIndex: Integer): Integer;
|
function TSQLite3Statement.ColumnInt(const ColumnIndex: Integer): Integer;
|
||||||
begin
|
begin
|
||||||
Result := sqlite3_column_int(FHandle, ColumnIndex);
|
Result := sqlite3_column_int(FHandle, ColumnIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.ColumnInt64(const ColumnIndex: Integer): Int64;
|
function TSQLite3Statement.ColumnInt64(const ColumnIndex: Integer): Int64;
|
||||||
begin
|
begin
|
||||||
Result := sqlite3_column_int64(FHandle, ColumnIndex);
|
Result := sqlite3_column_int64(FHandle, ColumnIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.ColumnName(const ColumnIndex: Integer): WideString;
|
function TSQLite3Statement.ColumnName(const ColumnIndex: Integer): WideString;
|
||||||
begin
|
begin
|
||||||
Result := UTF8ToStr(sqlite3_column_name(FHandle, ColumnIndex));
|
Result := UTF8ToStr(sqlite3_column_name(FHandle, ColumnIndex));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.ColumnText(const ColumnIndex: Integer): WideString;
|
function TSQLite3Statement.ColumnText(const ColumnIndex: Integer): WideString;
|
||||||
var
|
var
|
||||||
Len: Integer;
|
Len: Integer;
|
||||||
begin
|
begin
|
||||||
Len := ColumnBytes(ColumnIndex);
|
Len := ColumnBytes(ColumnIndex);
|
||||||
Result := UTF8ToStr(sqlite3_column_text(FHandle, ColumnIndex), Len);
|
Result := UTF8ToStr(sqlite3_column_text(FHandle, ColumnIndex), Len);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.ColumnType(const ColumnIndex: Integer): Integer;
|
function TSQLite3Statement.ColumnType(const ColumnIndex: Integer): Integer;
|
||||||
begin
|
begin
|
||||||
Result := sqlite3_column_type(FHandle, ColumnIndex);
|
Result := sqlite3_column_type(FHandle, ColumnIndex);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TSQLite3Statement.Create(OwnerDatabase: TSQLite3Database;
|
constructor TSQLite3Statement.Create(OwnerDatabase: TSQLite3Database;
|
||||||
const SQL: WideString);
|
const SQL: WideString);
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase := OwnerDatabase;
|
FOwnerDatabase := OwnerDatabase;
|
||||||
FOwnerDatabase.CheckHandle;
|
FOwnerDatabase.CheckHandle;
|
||||||
FOwnerDatabase.Check(
|
FOwnerDatabase.Check(
|
||||||
sqlite3_prepare_v2(FOwnerDatabase.Handle, PAnsiChar(StrToUTF8(SQL)), -1, FHandle, nil)
|
sqlite3_prepare_v2(FOwnerDatabase.Handle, PAnsiChar(StrToUTF8(SQL)), -1, FHandle, nil)
|
||||||
);
|
);
|
||||||
FOwnerDatabase.FStatementList.Add(Self);
|
FOwnerDatabase.FStatementList.Add(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TSQLite3Statement.Destroy;
|
destructor TSQLite3Statement.Destroy;
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.FStatementList.Remove(Self);
|
FOwnerDatabase.FStatementList.Remove(Self);
|
||||||
sqlite3_finalize(FHandle);
|
sqlite3_finalize(FHandle);
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.ParamIndexByName(const ParamName: WideString): Integer;
|
function TSQLite3Statement.ParamIndexByName(const ParamName: WideString): Integer;
|
||||||
begin
|
begin
|
||||||
Result := sqlite3_bind_parameter_index(FHandle, PAnsiChar(StrToUTF8(ParamName)));
|
Result := sqlite3_bind_parameter_index(FHandle, PAnsiChar(StrToUTF8(ParamName)));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.Reset;
|
procedure TSQLite3Statement.Reset;
|
||||||
begin
|
begin
|
||||||
sqlite3_reset(FHandle);
|
sqlite3_reset(FHandle);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TSQLite3Statement.Step: Integer;
|
function TSQLite3Statement.Step: Integer;
|
||||||
begin
|
begin
|
||||||
Result := sqlite3_step(FHandle);
|
Result := sqlite3_step(FHandle);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.StepAndReset;
|
procedure TSQLite3Statement.StepAndReset;
|
||||||
begin
|
begin
|
||||||
Step;
|
Step;
|
||||||
Reset;
|
Reset;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindBlob(const ParamName: WideString; Data: Pointer;
|
procedure TSQLite3Statement.BindBlob(const ParamName: WideString; Data: Pointer;
|
||||||
const Size: Integer);
|
const Size: Integer);
|
||||||
begin
|
begin
|
||||||
BindBlob(ParamIndexByName(ParamName), Data, Size);
|
BindBlob(ParamIndexByName(ParamName), Data, Size);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindDouble(const ParamName: WideString;
|
procedure TSQLite3Statement.BindDouble(const ParamName: WideString;
|
||||||
const Value: Double);
|
const Value: Double);
|
||||||
begin
|
begin
|
||||||
BindDouble(ParamIndexByName(ParamName), Value);
|
BindDouble(ParamIndexByName(ParamName), Value);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindInt(const ParamName: WideString;
|
procedure TSQLite3Statement.BindInt(const ParamName: WideString;
|
||||||
const Value: Integer);
|
const Value: Integer);
|
||||||
begin
|
begin
|
||||||
BindInt(ParamIndexByName(ParamName), Value);
|
BindInt(ParamIndexByName(ParamName), Value);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindInt64(const ParamName: WideString;
|
procedure TSQLite3Statement.BindInt64(const ParamName: WideString;
|
||||||
const Value: Int64);
|
const Value: Int64);
|
||||||
begin
|
begin
|
||||||
BindInt64(ParamIndexByName(ParamName), Value);
|
BindInt64(ParamIndexByName(ParamName), Value);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindNull(const ParamName: WideString);
|
procedure TSQLite3Statement.BindNull(const ParamName: WideString);
|
||||||
begin
|
begin
|
||||||
BindNull(ParamIndexByName(ParamName));
|
BindNull(ParamIndexByName(ParamName));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindText(const ParamName, Value: WideString);
|
procedure TSQLite3Statement.BindText(const ParamName, Value: WideString);
|
||||||
begin
|
begin
|
||||||
BindText(ParamIndexByName(ParamName), Value);
|
BindText(ParamIndexByName(ParamName), Value);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3Statement.BindZeroBlob(const ParamName: WideString;
|
procedure TSQLite3Statement.BindZeroBlob(const ParamName: WideString;
|
||||||
const Size: Integer);
|
const Size: Integer);
|
||||||
begin
|
begin
|
||||||
BindZeroBlob(ParamIndexByName(ParamName), Size);
|
BindZeroBlob(ParamIndexByName(ParamName), Size);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TSQLite3BlobHandler }
|
{ TSQLite3BlobHandler }
|
||||||
|
|
||||||
function TSQLite3BlobHandler.Bytes: Integer;
|
function TSQLite3BlobHandler.Bytes: Integer;
|
||||||
begin
|
begin
|
||||||
Result := sqlite3_blob_bytes(FHandle);
|
Result := sqlite3_blob_bytes(FHandle);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TSQLite3BlobHandler.Create(OwnerDatabase: TSQLite3Database; const Table,
|
constructor TSQLite3BlobHandler.Create(OwnerDatabase: TSQLite3Database; const Table,
|
||||||
Column: WideString; const RowID: Int64; const WriteAccess: Boolean);
|
Column: WideString; const RowID: Int64; const WriteAccess: Boolean);
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase := OwnerDatabase;
|
FOwnerDatabase := OwnerDatabase;
|
||||||
FOwnerDatabase.CheckHandle;
|
FOwnerDatabase.CheckHandle;
|
||||||
FOwnerDatabase.Check(
|
FOwnerDatabase.Check(
|
||||||
sqlite3_blob_open(FOwnerDatabase.FHandle, 'main', PAnsiChar(StrToUTF8(Table)),
|
sqlite3_blob_open(FOwnerDatabase.FHandle, 'main', PAnsiChar(StrToUTF8(Table)),
|
||||||
PAnsiChar(StrToUTF8(Column)), RowID, Ord(WriteAccess), FHandle)
|
PAnsiChar(StrToUTF8(Column)), RowID, Ord(WriteAccess), FHandle)
|
||||||
);
|
);
|
||||||
FOwnerDatabase.FBlobHandlerList.Add(Self);
|
FOwnerDatabase.FBlobHandlerList.Add(Self);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TSQLite3BlobHandler.Destroy;
|
destructor TSQLite3BlobHandler.Destroy;
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.FBlobHandlerList.Remove(Self);
|
FOwnerDatabase.FBlobHandlerList.Remove(Self);
|
||||||
sqlite3_blob_close(FHandle);
|
sqlite3_blob_close(FHandle);
|
||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3BlobHandler.Read(Buffer: Pointer; const Size,
|
procedure TSQLite3BlobHandler.Read(Buffer: Pointer; const Size,
|
||||||
Offset: Integer);
|
Offset: Integer);
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.Check(sqlite3_blob_read(FHandle, Buffer, Size, Offset));
|
FOwnerDatabase.Check(sqlite3_blob_read(FHandle, Buffer, Size, Offset));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSQLite3BlobHandler.Write(Buffer: Pointer; const Size,
|
procedure TSQLite3BlobHandler.Write(Buffer: Pointer; const Size,
|
||||||
Offset: Integer);
|
Offset: Integer);
|
||||||
begin
|
begin
|
||||||
FOwnerDatabase.Check(sqlite3_blob_write(FHandle, Buffer, Size, Offset));
|
FOwnerDatabase.Check(sqlite3_blob_write(FHandle, Buffer, Size, Offset));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|||||||
Reference in New Issue
Block a user