-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimplesqlite3.pas
More file actions
198 lines (176 loc) · 6.56 KB
/
simplesqlite3.pas
File metadata and controls
198 lines (176 loc) · 6.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
(*
@AI:unit-summary: This Pascal unit provides functionality for managing SQLite3 database connections, including opening and closing connections, creating and finalizing SQL queries, checking for the existence of tables and specific records (builds) in the database based on identifiers or QR codes.
*)
unit SimpleSQLite3;
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, SQLite3Conn, SQLDB;
function OpenDB (const dbName: string; out DBObj: TSQLite3Connection): boolean;
procedure CloseDB (var DBObj: tSqlite3Connection);
function NewQuery (DBObj: TSQLite3Connection): TSQLQuery;
procedure EndQuery (var Query: tSQLQuery);
function TableExists (var DBObj: TSQLite3Connection; TableName: string): boolean;
// Just some quick query functions
function BuildExists (DBObj: TSQLite3Connection; BuildID: integer): boolean; overload;
function BuildExists (DBObj: TSQLite3Connection; QRCode: string): boolean; overload;
implementation
function OpenDB (const dbName: string; out DBObj: TSQLite3Connection): boolean;
(*
@AI:summary: This function opens a SQLite3 database connection using the specified database name. This routine also establishes the transaction objects, and a busy_timeout.
@AI:params: dbName: The filename of the database to be opened.
@AI:params: DBObj: An output parameter that will hold the database connection object upon successful opening.
@AI:returns: A boolean indicating whether the database connection was successfully opened.
*)
var
conSQLite3: TSQLite3Connection;
transSQLite3: TSQLTransaction;
begin
Result := False;
// Create components
conSQLite3 := TSQLite3Connection.Create(nil);
transSQLite3 := TSQLTransaction.Create(nil);
try
// Link transaction to database
transSQLite3.Database := conSQLite3;
conSQLite3.Transaction := transSQLite3;
// Setup database properties
conSQLite3.DatabaseName := dbName;
conSQLite3.HostName := 'localhost';
conSQLite3.CharSet := 'UTF8';
// Open database
conSQLite3.Params.Values['busy_timeout'] := '5000';
conSQLite3.Open;
// Ensure database is open before returning
if conSQLite3.Connected then begin
DBObj := conSQLite3;
Result := True;
end else begin
conSQLite3.Close;
end;
except
on E: Exception do begin
conSQLite3.Close;
transSQLite3.Free;
conSQLite3.Free;
Result := False;
end;
end;
end;
procedure CloseDB (var DBObj: TSQLite3Connection);
(*
@AI:summary: This function closes a SQlite3 database file connection safely. It also cleans up any transactions that are open prior to clearing the DBobj variable
@AI:params: DBObj: Represents the database connection object that needs to be closed.
@AI:returns: No output is expected.
*)
begin
// disconnect
if Assigned(DBObj) then begin
if DBObj.Connected then begin
TSQLTransaction(DBObj.Transaction).Commit;
DBObj.Close;
end;
// release
TSQLTransaction(DBObj.Transaction).Free;
DBObj.Free;
end;
end;
function NewQuery (DBObj: TSQLite3Connection): TSQLQuery;
(*
@AI:summary: Creates a new SQL query object associated with a given SQLite3 database connection. This prepares the related Transaction object already assigned to the DBObj.
@AI:params: DBObj: The database connection object used to execute the SQL queries.
@AI:returns: A new SQL query object for interacting with the database.
*)
var
q: TSQLQuery;
begin
q := TSQLQuery.Create(nil);
q.Database := DBObj;
q.Transaction := DBObj.Transaction;
Result := q;
end;
procedure EndQuery (var Query: tSQLQuery);
(*
@AI:summary: This function likely finalizes or closes a SQL query operation.
@AI:params: Query: Represents the SQL query object that is being processed or terminated.
@AI:returns: No output is expected.
*)
var
LocalDB: TSQLite3Connection;
LastTransCount: integer;
begin
LocalDB := TSQLite3Connection(Query.DataBase);
LastTransCount := LocalDB.TransactionCount;
LocalDB.Transaction.Commit;
while LocalDB.TransactionCount > 1 do begin
LocalDB.Transaction.Commit;
if LastTransCount <> LocalDB.TransactionCount then begin
LastTransCount := LocalDB.TransactionCount;
LocalDB.Transaction.Commit;
end;
end;
Query.Close;
Query.Free;
end;
function TableExists (var DBObj: TSQLite3Connection; TableName: string): boolean;
(*
@AI:summary: Checks if a specified table exists in the given SQLite database connection.
@AI:params: DBObj: The database connection object used to access the SQLite database.
@AI:params: TableName: The name of the table to check for existence in the database.
@AI:returns: Returns true if the table exists, otherwise false.
*)
var
dbList: TStringList;
begin
dbList := TStringList.Create;
try
DBObj.GetTableNames(dbList);
Result := dbList.IndexOf(TableName) <> -1;
finally
dbList.Free;
end;
end;
function BuildExists (DBObj: TSQLite3Connection; BuildID: integer): boolean; overload;
(*
@AI:summary: Checks if a specific build exists in the database. A build is typically a computer case, or a set of components that are part of a build.
@AI:params: DBObj: The database connection object used to interact with the SQLite database.
@AI:params: BuildID: The unique identifier for the build being checked for existence.
@AI:returns: Returns true if the build exists, otherwise false.
@AI:notes: This is a PASCAL OVERRIDEN function. This function looks at the BuildID.
*)
var
q: TSQLQuery;
r: integer;
begin
q := NewQuery(DBObj);
q.SQL.Text := 'select count(BuildID) BuildCount from BuildList where BuildID=:BuildID';
q.Params.ParamValues['BuildID'] := BuildID;
q.Open;
r := q.FieldByName('BuildCount').AsInteger;
EndQuery(q);
Result := r = 1;
end;
function BuildExists (DBObj: TSQLite3Connection; QRCode: string): boolean; overload;
(*
@AI:summary: This function checks if a specific QR code exists in the database.
@AI:params: DBObj: Represents the database connection to be used for the query.
@AI:params: QRCode: The QR code string that needs to be checked for existence in the database.
@AI:returns: A boolean indicating whether the QR code exists in the database.
@AI:notes: This is a PASCAL OVERRIDEN function. This function looks at the QRCode.
*)
var
q: TSQLQuery;
r: integer;
begin
q := NewQuery(DBObj);
// BuildList stores QR strings in the BuildQR column defined in
// databasemanager.DefineBuildList. Query that field to avoid a
// "QRCode" reference that doesn't exist in the table schema.
q.SQL.Text := 'select count(BuildID) BuildCount from BuildList where BuildQR=:BuildQR';
q.Params.ParamValues['BuildQR'] := QRCode;
q.Open;
r := q.FieldByName('BuildCount').AsInteger;
EndQuery(q);
Result := r = 1;
end;
end.