1 // Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
2 //
3 // Use of this source code is governed by an MIT-style
4 // license that can be found in the LICENSE file.
5 
6 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
7 #include <stdio.h>
8 #include <sqlite3-binding.h>
9 
10 extern int unlock_notify_wait(sqlite3 *db);
11 
12 int
_sqlite3_step_blocking(sqlite3_stmt * stmt)13 _sqlite3_step_blocking(sqlite3_stmt *stmt)
14 {
15   int rv;
16   sqlite3* db;
17 
18   db = sqlite3_db_handle(stmt);
19   for (;;) {
20     rv = sqlite3_step(stmt);
21     if (rv != SQLITE_LOCKED) {
22       break;
23     }
24     if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
25       break;
26     }
27     rv = unlock_notify_wait(db);
28     if (rv != SQLITE_OK) {
29       break;
30     }
31     sqlite3_reset(stmt);
32   }
33 
34   return rv;
35 }
36 
37 int
_sqlite3_step_row_blocking(sqlite3_stmt * stmt,long long * rowid,long long * changes)38 _sqlite3_step_row_blocking(sqlite3_stmt* stmt, long long* rowid, long long* changes)
39 {
40   int rv;
41   sqlite3* db;
42 
43   db = sqlite3_db_handle(stmt);
44   for (;;) {
45     rv = sqlite3_step(stmt);
46     if (rv!=SQLITE_LOCKED) {
47       break;
48     }
49     if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
50       break;
51     }
52     rv = unlock_notify_wait(db);
53     if (rv != SQLITE_OK) {
54       break;
55     }
56     sqlite3_reset(stmt);
57   }
58 
59   *rowid = (long long) sqlite3_last_insert_rowid(db);
60   *changes = (long long) sqlite3_changes(db);
61   return rv;
62 }
63 
64 int
_sqlite3_prepare_v2_blocking(sqlite3 * db,const char * zSql,int nBytes,sqlite3_stmt ** ppStmt,const char ** pzTail)65 _sqlite3_prepare_v2_blocking(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail)
66 {
67   int rv;
68 
69   for (;;) {
70     rv = sqlite3_prepare_v2(db, zSql, nBytes, ppStmt, pzTail);
71     if (rv!=SQLITE_LOCKED) {
72       break;
73     }
74     if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
75       break;
76     }
77     rv = unlock_notify_wait(db);
78     if (rv != SQLITE_OK) {
79       break;
80     }
81   }
82 
83   return rv;
84 }
85 #endif
86