SQLITE_STATIC -> SQLITE_TRANSIENT in BindBlob()

This commit is contained in:
2012-10-08 01:46:19 +07:00
parent 8caeb0d233
commit 09d8674805
3 changed files with 1453 additions and 1453 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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.

View File

@@ -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.