1 /* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 #ifndef TENSORFLOW_CORE_LIB_DB_SQLITE_H_
16 #define TENSORFLOW_CORE_LIB_DB_SQLITE_H_
17
18 #include <mutex>
19
20 #include "sqlite3.h"
21 #include "tensorflow/core/lib/core/refcount.h"
22 #include "tensorflow/core/lib/core/status.h"
23 #include "tensorflow/core/lib/core/stringpiece.h"
24 #include "tensorflow/core/platform/macros.h"
25 #include "tensorflow/core/platform/thread_annotations.h"
26 #include "tensorflow/core/platform/types.h"
27
28 /// TensorFlow SQLite Veneer
29 ///
30 /// - Memory safety
31 /// - Less boilerplate
32 /// - Removes deprecated stuff
33 /// - Pretends UTF16 doesn't exist
34 /// - Transaction compile-time safety
35 /// - Statically loads our native extensions
36 /// - Error reporting via tensorflow::Status et al.
37 ///
38 /// SQLite>=3.8.2 needs to be supported until April 2019, which is when
39 /// Ubuntu 14.04 LTS becomes EOL.
40
41 namespace tensorflow {
42
43 class SqliteLock;
44 class SqliteStatement;
45 class SqliteTransaction;
46
47 /// \brief SQLite connection object.
48 ///
49 /// The SQLite connection is closed automatically by the destructor.
50 /// Reference counting ensures that happens after its statements are
51 /// destructed.
52 ///
53 /// Instances are reference counted and can be shared between threads.
54 /// This class offers the same thread safety behaviors as the SQLite
55 /// API itself.
56 ///
57 /// This veneer uses auto-commit mode by default, which means a 4ms
58 /// fsync() happens after every write unless a SqliteTransaction is
59 /// used or WAL mode is enabled beforehand.
60 class TF_LOCKABLE Sqlite : public core::RefCounted {
61 public:
62 /// \brief Closes SQLite connection, which can take milliseconds.
63 virtual ~Sqlite();
64
65 /// \brief Opens SQLite database file.
66 ///
67 /// Most users will want to set flags to SQLITE_OPEN_READWRITE |
68 /// SQLITE_OPEN_CREATE. There are many other open flags; here are
69 /// notes on a few of them:
70 ///
71 /// - SQLITE_OPEN_READONLY: Allowed if no WAL journal is active.
72 /// - SQLITE_OPEN_SHAREDCACHE: Will be ignored because this veneer
73 /// doesn't support the unlock notify API.
74 /// - SQLITE_OPEN_NOMUTEX: Means access to this connection MUST be
75 /// serialized by the caller in accordance with the same contracts
76 /// implemented by this API.
77 ///
78 /// This function sets PRAGMA values from TF_SQLITE_* environment
79 /// variables. See sqlite.cc to learn more.
80 static Status Open(const string& path, int flags, Sqlite** db);
81
82 /// \brief Creates SQLite statement.
83 ///
84 /// This routine should never fail if sql is valid and does not
85 /// reference tables. When tables are referenced, system calls are
86 /// needed which can take microseconds. When the schema changes, this
87 /// routine will retry automatically and then possibly fail.
88 ///
89 /// The returned statement holds a reference to this object.
90 Status Prepare(const StringPiece& sql, SqliteStatement* stmt);
91 SqliteStatement PrepareOrDie(const StringPiece& sql);
92
93 /// \brief Returns extended result code of last error.
94 ///
95 /// If the most recent API call was successful, the result is
96 /// undefined. The legacy result code can be obtained by saying
97 /// errcode() & 0xff.
errcode()98 int errcode() const TF_EXCLUSIVE_LOCKS_REQUIRED(this) {
99 return sqlite3_extended_errcode(db_);
100 }
101
102 /// \brief Returns pointer to current error message state.
errmsg()103 const char* errmsg() const TF_EXCLUSIVE_LOCKS_REQUIRED(this) {
104 return sqlite3_errmsg(db_);
105 }
106
107 /// \brief Returns rowid assigned to last successful insert.
last_insert_rowid()108 int64_t last_insert_rowid() const TF_EXCLUSIVE_LOCKS_REQUIRED(this) {
109 return sqlite3_last_insert_rowid(db_);
110 }
111
112 /// \brief Returns number of rows directly changed by last write.
changes()113 int64_t changes() const TF_EXCLUSIVE_LOCKS_REQUIRED(this) {
114 return sqlite3_changes(db_);
115 }
116
117 private:
118 friend class SqliteLock;
119 friend class SqliteStatement;
120 friend class SqliteTransaction;
121
Sqlite(sqlite3 * db,sqlite3_stmt * begin,sqlite3_stmt * commit,sqlite3_stmt * rollback)122 Sqlite(sqlite3* db, sqlite3_stmt* begin, sqlite3_stmt* commit,
123 sqlite3_stmt* rollback) noexcept
124 : db_(db), begin_(begin), commit_(commit), rollback_(rollback) {}
125
126 sqlite3* const db_;
127 sqlite3_stmt* const begin_;
128 sqlite3_stmt* const commit_;
129 sqlite3_stmt* const rollback_;
130 bool is_in_transaction_ = false;
131
132 TF_DISALLOW_COPY_AND_ASSIGN(Sqlite);
133 };
134
135 /// \brief SQLite prepared statement.
136 ///
137 /// Instances can only be shared between threads if caller serializes
138 /// access from first Bind*() to *Reset().
139 ///
140 /// When reusing a statement in a loop, be certain to not have jumps
141 /// betwixt Bind*() and *Reset().
142 class SqliteStatement {
143 public:
144 /// \brief Initializes an empty statement to be assigned later.
145 SqliteStatement() noexcept = default;
146
147 /// \brief Finalizes statement.
148 ///
149 /// This can take milliseconds if it was blocking the Sqlite
150 /// connection object from being freed.
~SqliteStatement()151 ~SqliteStatement() {
152 sqlite3_finalize(stmt_);
153 if (db_ != nullptr) db_->Unref();
154 }
155
156 /// \brief Returns true if statement is initialized.
157 explicit operator bool() const { return stmt_ != nullptr; }
158
159 /// \brief Returns SQL text from when this query was prepared.
sql()160 const char* sql() const { return sqlite3_sql(stmt_); }
161
162 /// \brief Number of bytes bound since last *Reset().
size()163 uint64 size() { return size_; }
164
165 /// \brief Executes query for fetching arbitrary rows.
166 ///
167 /// `is_done` will always be set to true unless SQLITE_ROW is
168 /// returned by the underlying API. If status() is already in an
169 /// error state, then this method is a no-op and the existing status
170 /// is returned.
171 ///
172 /// The OrDie version returns `!is_done` which, if true, indicates a
173 /// row is available.
174 ///
175 /// This statement should be Reset() or destructed when finished with
176 /// the result.
177 Status Step(bool* is_done);
178 bool StepOrDie() TF_MUST_USE_RESULT;
179
180 /// \brief Executes query when only one row is desired.
181 ///
182 /// If a row isn't returned, an internal error Status is returned
183 /// that won't be reflected in the connection error state.
184 ///
185 /// This statement should be Reset() or destructed when finished with
186 /// the result.
187 Status StepOnce();
188 const SqliteStatement& StepOnceOrDie();
189
190 /// \brief Executes query, ensures zero rows returned, then Reset().
191 ///
192 /// If a row is returned, an internal error Status is returned that
193 /// won't be reflected in the connection error state.
194 Status StepAndReset();
195 void StepAndResetOrDie();
196
197 /// \brief Resets statement so it can be executed again.
198 ///
199 /// Implementation note: This method diverges from canonical API
200 /// behavior by calling sqlite3_clear_bindings() in addition to
201 /// sqlite3_reset(). That makes the veneer safer; we haven't found a
202 /// super compelling reason yet to call them independently.
203 void Reset();
204
205 /// \brief Binds signed 64-bit integer to 1-indexed query parameter.
BindInt(int parameter,int64_t value)206 void BindInt(int parameter, int64_t value) {
207 Update(sqlite3_bind_int64(stmt_, parameter, value), parameter);
208 size_ += sizeof(int64_t);
209 }
BindInt(const char * parameter,int64_t value)210 void BindInt(const char* parameter, int64_t value) {
211 BindInt(GetParameterIndex(parameter), value);
212 }
213
214 /// \brief Binds double to 1-indexed query parameter.
BindDouble(int parameter,double value)215 void BindDouble(int parameter, double value) {
216 Update(sqlite3_bind_double(stmt_, parameter, value), parameter);
217 size_ += sizeof(double);
218 }
BindDouble(const char * parameter,double value)219 void BindDouble(const char* parameter, double value) {
220 BindDouble(GetParameterIndex(parameter), value);
221 }
222
223 /// \brief Copies UTF-8 text to 1-indexed query parameter.
224 ///
225 /// If NUL characters are present, they will still go in the DB and
226 /// be successfully retrieved by ColumnString(); however, the
227 /// behavior of these values with SQLite functions is undefined.
228 ///
229 /// When using the unsafe methods, the data must not be changed or
230 /// freed until this statement is Reset() or finalized.
BindText(int parameter,const StringPiece & text)231 void BindText(int parameter, const StringPiece& text) {
232 Update(sqlite3_bind_text64(stmt_, parameter, text.data(), text.size(),
233 SQLITE_TRANSIENT, SQLITE_UTF8),
234 parameter);
235 size_ += text.size();
236 }
BindText(const char * parameter,const StringPiece & text)237 void BindText(const char* parameter, const StringPiece& text) {
238 BindText(GetParameterIndex(parameter), text);
239 }
BindTextUnsafe(int parameter,const StringPiece & text)240 void BindTextUnsafe(int parameter, const StringPiece& text) {
241 Update(sqlite3_bind_text64(stmt_, parameter, text.data(), text.size(),
242 SQLITE_STATIC, SQLITE_UTF8),
243 parameter);
244 size_ += text.size();
245 }
BindTextUnsafe(const char * parameter,const StringPiece & text)246 void BindTextUnsafe(const char* parameter, const StringPiece& text) {
247 BindTextUnsafe(GetParameterIndex(parameter), text);
248 }
249
250 /// \brief Copies binary data to 1-indexed query parameter.
251 ///
252 /// When using the unsafe methods, the data must not be changed or
253 /// freed until this statement is Reset() or finalized.
BindBlob(int parameter,const StringPiece & blob)254 void BindBlob(int parameter, const StringPiece& blob) {
255 Update(sqlite3_bind_blob64(stmt_, parameter, blob.data(), blob.size(),
256 SQLITE_TRANSIENT),
257 parameter);
258 size_ += blob.size();
259 }
BindBlob(const char * parameter,const StringPiece & blob)260 void BindBlob(const char* parameter, const StringPiece& blob) {
261 BindBlob(GetParameterIndex(parameter), blob);
262 }
BindBlobUnsafe(int parameter,const StringPiece & blob)263 void BindBlobUnsafe(int parameter, const StringPiece& blob) {
264 Update(sqlite3_bind_blob64(stmt_, parameter, blob.data(), blob.size(),
265 SQLITE_STATIC),
266 parameter);
267 size_ += blob.size();
268 }
BindBlobUnsafe(const char * parameter,const StringPiece & text)269 void BindBlobUnsafe(const char* parameter, const StringPiece& text) {
270 BindBlobUnsafe(GetParameterIndex(parameter), text);
271 }
272
273 /// \brief Returns number of columns in result set.
ColumnCount()274 int ColumnCount() const TF_MUST_USE_RESULT {
275 return sqlite3_column_count(stmt_);
276 }
277
278 /// \brief Returns type of 0-indexed column value in row data.
279 ///
280 /// Please note that SQLite is dynamically typed and the type of a
281 /// particular column can vary from row to row.
ColumnType(int column)282 int ColumnType(int column) const TF_MUST_USE_RESULT {
283 return sqlite3_column_type(stmt_, column);
284 }
285
286 /// \brief Returns 0-indexed column from row result coerced as an integer.
ColumnInt(int column)287 int64_t ColumnInt(int column) const TF_MUST_USE_RESULT {
288 return sqlite3_column_int64(stmt_, column);
289 }
290
291 /// \brief Returns 0-indexed column from row result coerced as a double.
ColumnDouble(int column)292 double ColumnDouble(int column) const TF_MUST_USE_RESULT {
293 return sqlite3_column_double(stmt_, column);
294 }
295
296 /// \brief Copies 0-indexed column from row result coerced as a string.
297 ///
298 /// NULL values are returned as empty string. This method should be
299 /// used for both BLOB and TEXT columns. See also: ColumnType().
ColumnString(int column)300 string ColumnString(int column) const TF_MUST_USE_RESULT {
301 auto data = sqlite3_column_blob(stmt_, column);
302 if (data == nullptr) return "";
303 return {static_cast<const char*>(data),
304 static_cast<size_t>(ColumnSize(column))};
305 }
306
307 /// \brief Returns pointer to binary data at 0-indexed column.
308 ///
309 /// Empty values are returned as NULL. The returned memory will no
310 /// longer be valid the next time Step() or Reset() is called. No NUL
311 /// terminator is added.
ColumnStringUnsafe(int column)312 StringPiece ColumnStringUnsafe(int column) const TF_MUST_USE_RESULT {
313 return {static_cast<const char*>(sqlite3_column_blob(stmt_, column)),
314 static_cast<size_t>(ColumnSize(column))};
315 }
316
317 /// \brief Returns number of bytes stored at 0-indexed column.
ColumnSize(int column)318 int ColumnSize(int column) const TF_MUST_USE_RESULT {
319 return sqlite3_column_bytes(stmt_, column);
320 }
321
322 /// \brief Move constructor, after which <other> is reset to empty.
SqliteStatement(SqliteStatement && other)323 SqliteStatement(SqliteStatement&& other) noexcept
324 : db_(other.db_), stmt_(other.stmt_), bind_error_(other.bind_error_) {
325 other.db_ = nullptr;
326 other.stmt_ = nullptr;
327 other.bind_error_ = SQLITE_OK;
328 }
329
330 /// \brief Move assignment, after which <other> is reset to empty.
331 SqliteStatement& operator=(SqliteStatement&& other) noexcept {
332 if (&other != this) {
333 if (db_ != nullptr) db_->Unref();
334 if (stmt_ != nullptr) sqlite3_finalize(stmt_);
335 db_ = other.db_;
336 stmt_ = other.stmt_;
337 bind_error_ = other.bind_error_;
338 size_ = other.size_;
339 other.db_ = nullptr;
340 other.stmt_ = nullptr;
341 other.bind_error_ = SQLITE_OK;
342 other.size_ = 0;
343 }
344 return *this;
345 }
346
347 private:
348 friend class Sqlite;
349
SqliteStatement(Sqlite * db,sqlite3_stmt * stmt)350 SqliteStatement(Sqlite* db, sqlite3_stmt* stmt) noexcept
351 : db_(db), stmt_(stmt) {
352 db_->Ref();
353 }
354
Update(int rc,int parameter)355 void Update(int rc, int parameter) {
356 // Binding strings can fail if they exceed length limit.
357 if (TF_PREDICT_FALSE(rc != SQLITE_OK)) {
358 if (bind_error_ == SQLITE_OK) {
359 bind_error_ = rc;
360 bind_error_parameter_ = parameter;
361 }
362 }
363 }
364
GetParameterIndex(const char * parameter)365 int GetParameterIndex(const char* parameter) {
366 int index = sqlite3_bind_parameter_index(stmt_, parameter);
367 DCHECK(index > 0); // OK to compile away since it'll fail again
368 return index;
369 }
370
371 Sqlite* db_ = nullptr;
372 sqlite3_stmt* stmt_ = nullptr;
373 int bind_error_ = SQLITE_OK;
374 int bind_error_parameter_ = 0;
375 uint64 size_ = 0;
376
377 TF_DISALLOW_COPY_AND_ASSIGN(SqliteStatement);
378 };
379
380 /// \brief Reentrant SQLite connection object lock
381 ///
382 /// This is a no-op if SQLITE_OPEN_NOMUTEX was used.
383 class TF_SCOPED_LOCKABLE SqliteLock {
384 public:
SqliteLock(Sqlite & db)385 explicit SqliteLock(Sqlite& db) TF_EXCLUSIVE_LOCK_FUNCTION(db)
386 : mutex_(sqlite3_db_mutex(db.db_)) {
387 sqlite3_mutex_enter(mutex_);
388 }
SqliteLock(Sqlite & db,std::try_to_lock_t)389 SqliteLock(Sqlite& db, std::try_to_lock_t) TF_EXCLUSIVE_LOCK_FUNCTION(db)
390 : mutex_(sqlite3_db_mutex(db.db_)) {
391 if (TF_PREDICT_FALSE(sqlite3_mutex_try(mutex_) != SQLITE_OK)) {
392 is_locked_ = false;
393 }
394 }
TF_UNLOCK_FUNCTION()395 ~SqliteLock() TF_UNLOCK_FUNCTION() {
396 if (is_locked_) sqlite3_mutex_leave(mutex_);
397 }
398 explicit operator bool() const { return is_locked_; }
399
400 private:
401 sqlite3_mutex* const mutex_;
402 bool is_locked_ = true;
403 TF_DISALLOW_COPY_AND_ASSIGN(SqliteLock);
404 };
405 #define SqliteLock(x) static_assert(0, "sqlite_lock_decl_missing_name");
406
407 /// \brief SQLite transaction scope.
408 ///
409 /// This class acquires an exclusive lock on the connection object (if
410 /// mutexes weren't disabled) and runs BEGIN / ROLLBACK automatically.
411 /// Unlike SqliteLock this scope is non-reentrant. To avoid program
412 /// crashes, business logic should use the TF_EXCLUSIVE_LOCK_FUNCTION and
413 /// TF_LOCKS_EXCLUDED annotations as much as possible.
414 class TF_SCOPED_LOCKABLE SqliteTransaction {
415 public:
416 /// \brief Locks db and begins deferred transaction.
417 ///
418 /// This will crash if a transaction is already active.
419 explicit SqliteTransaction(Sqlite& db) TF_EXCLUSIVE_LOCK_FUNCTION(db);
420
421 /// \brief Runs ROLLBACK and unlocks.
422 ~SqliteTransaction() TF_UNLOCK_FUNCTION();
423
424 /// \brief Commits transaction.
425 ///
426 /// If this is successful, a new transaction will be started, which
427 /// is rolled back when exiting the scope.
428 Status Commit();
429
430 private:
431 void Begin();
432 Sqlite* const db_;
433
434 TF_DISALLOW_COPY_AND_ASSIGN(SqliteTransaction);
435 };
436
437 #define SQLITE_EXCLUSIVE_TRANSACTIONS_REQUIRED(...) \
438 TF_EXCLUSIVE_LOCKS_REQUIRED(__VA_ARGS__)
439 #define SQLITE_TRANSACTIONS_EXCLUDED(...) TF_LOCKS_EXCLUDED(__VA_ARGS__)
440
PrepareOrDie(const StringPiece & sql)441 inline SqliteStatement Sqlite::PrepareOrDie(const StringPiece& sql) {
442 SqliteStatement stmt;
443 TF_CHECK_OK(Prepare(sql, &stmt));
444 return stmt;
445 }
446
447 } // namespace tensorflow
448
449 #endif // TENSORFLOW_CORE_LIB_DB_SQLITE_H_
450