sqlite3_accessor.cc 53 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. // Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <sqlite3.h>
  15. #include <string>
  16. #include <utility>
  17. #include <vector>
  18. #include <exceptions/exceptions.h>
  19. #include <dns/name.h>
  20. #include <datasrc/sqlite3_accessor.h>
  21. #include <datasrc/logger.h>
  22. #include <datasrc/data_source.h>
  23. #include <datasrc/factory.h>
  24. #include <datasrc/database.h>
  25. #include <util/filename.h>
  26. using namespace std;
  27. using namespace isc::data;
  28. namespace {
  29. // Expected schema. The major version must match else there is an error. If
  30. // the minor version of the database is less than this, a warning is output.
  31. //
  32. // It is assumed that a program written to run on m.n of the database will run
  33. // with a database version m.p, where p is any number. However, if p < n,
  34. // we assume that the database structure was upgraded for some reason, and that
  35. // some advantage may result if the database is upgraded. Conversely, if p > n,
  36. // The database is at a later version than the program was written for and the
  37. // program may not be taking advantage of features (possibly performance
  38. // improvements) added to the database.
  39. const int SQLITE_SCHEMA_MAJOR_VERSION = 2;
  40. const int SQLITE_SCHEMA_MINOR_VERSION = 1;
  41. }
  42. namespace isc {
  43. namespace datasrc {
  44. // The following enum and char* array define the SQL statements commonly
  45. // used in this implementation. Corresponding prepared statements (of
  46. // type sqlite3_stmt*) are maintained in the statements_ array of the
  47. // SQLite3Parameters structure.
  48. enum StatementID {
  49. ZONE = 0,
  50. ANY = 1,
  51. ANY_SUB = 2,
  52. BEGIN = 3,
  53. COMMIT = 4,
  54. ROLLBACK = 5,
  55. DEL_ZONE_RECORDS = 6,
  56. ADD_RECORD = 7,
  57. DEL_RECORD = 8,
  58. ITERATE_RECORDS = 9,
  59. ITERATE_NSEC3 = 10,
  60. FIND_PREVIOUS = 11,
  61. ADD_RECORD_DIFF = 12,
  62. LOW_DIFF_ID = 13,
  63. HIGH_DIFF_ID = 14,
  64. DIFF_RECS = 15,
  65. NSEC3 = 16,
  66. NSEC3_PREVIOUS = 17,
  67. NSEC3_LAST = 18,
  68. ADD_NSEC3_RECORD = 19,
  69. DEL_ZONE_NSEC3_RECORDS = 20,
  70. DEL_NSEC3_RECORD = 21,
  71. ADD_ZONE = 22,
  72. DELETE_ZONE = 23,
  73. NUM_STATEMENTS = 24
  74. };
  75. const char* const text_statements[NUM_STATEMENTS] = {
  76. // note for ANY and ITERATE: the order of the SELECT values is
  77. // specifically chosen to match the enum values in RecordColumns
  78. "SELECT id FROM zones WHERE name=?1 AND rdclass = ?2", // ZONE
  79. "SELECT rdtype, ttl, sigtype, rdata FROM records " // ANY
  80. "WHERE zone_id=?1 AND name=?2",
  81. // ANY_SUB:
  82. // This query returns records in the specified zone for the domain
  83. // matching the passed name, and its sub-domains.
  84. "SELECT rdtype, ttl, sigtype, rdata "
  85. "FROM records WHERE zone_id=?1 AND rname LIKE ?2",
  86. "BEGIN", // BEGIN
  87. "COMMIT", // COMMIT
  88. "ROLLBACK", // ROLLBACK
  89. "DELETE FROM records WHERE zone_id=?1", // DEL_ZONE_RECORDS
  90. "INSERT INTO records " // ADD_RECORD
  91. "(zone_id, name, rname, ttl, rdtype, sigtype, rdata) "
  92. "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
  93. "DELETE FROM records WHERE zone_id=?1 AND name=?2 " // DEL_RECORD
  94. "AND rdtype=?3 AND rdata=?4",
  95. // ITERATE_RECORDS:
  96. // The following iterates the whole zone in the records table.
  97. "SELECT rdtype, ttl, sigtype, rdata, name FROM records "
  98. "WHERE zone_id = ?1 ORDER BY rname, rdtype",
  99. // ITERATE_NSEC3:
  100. // The following iterates the whole zone in the nsec3 table. As the
  101. // RRSIGs are for NSEC3s, we can hardcode the sigtype.
  102. "SELECT rdtype, ttl, \"NSEC3\", rdata, owner FROM nsec3 "
  103. "WHERE zone_id = ?1 ORDER BY hash, rdtype",
  104. /*
  105. * This one looks for previous name with NSEC record. It is done by
  106. * using the reversed name. The NSEC is checked because we need to
  107. * skip glue data, which don't have the NSEC.
  108. */
  109. "SELECT name FROM records " // FIND_PREVIOUS
  110. "WHERE zone_id=?1 AND rdtype = 'NSEC' AND "
  111. "rname < ?2 ORDER BY rname DESC LIMIT 1",
  112. "INSERT INTO diffs " // ADD_RECORD_DIFF
  113. "(zone_id, version, operation, name, rrtype, ttl, rdata) "
  114. "VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)",
  115. // Two statements to select the lowest ID and highest ID in a set of
  116. // differences.
  117. "SELECT id FROM diffs " // LOW_DIFF_ID
  118. "WHERE zone_id=?1 AND version=?2 and OPERATION=?3 "
  119. "ORDER BY id ASC LIMIT 1",
  120. "SELECT id FROM diffs " // HIGH_DIFF_ID
  121. "WHERE zone_id=?1 AND version=?2 and OPERATION=?3 "
  122. "ORDER BY id DESC LIMIT 1",
  123. // In the next statement, note the redundant ID. This is to ensure
  124. // that the columns match the column IDs passed to the iterator
  125. "SELECT rrtype, ttl, id, rdata, name FROM diffs " // DIFF_RECS
  126. "WHERE zone_id=?1 AND id>=?2 and id<=?3 "
  127. "ORDER BY id ASC",
  128. // NSEC3: Query to get the NSEC3 records
  129. //
  130. // The "1" in SELECT is for positioning the rdata column to the
  131. // expected position, so we can reuse the same code as for other
  132. // lookups.
  133. "SELECT rdtype, ttl, 1, rdata FROM nsec3 WHERE zone_id=?1 AND "
  134. "hash=?2",
  135. // NSEC3_PREVIOUS: For getting the previous NSEC3 hash
  136. "SELECT DISTINCT hash FROM nsec3 WHERE zone_id=?1 AND hash < ?2 "
  137. "ORDER BY hash DESC LIMIT 1",
  138. // NSEC3_LAST: And for wrap-around
  139. "SELECT DISTINCT hash FROM nsec3 WHERE zone_id=?1 "
  140. "ORDER BY hash DESC LIMIT 1",
  141. // ADD_NSEC3_RECORD: Add NSEC3-related (NSEC3 or NSEC3-covering RRSIG) RR
  142. "INSERT INTO nsec3 (zone_id, hash, owner, ttl, rdtype, rdata) "
  143. "VALUES (?1, ?2, ?3, ?4, ?5, ?6)",
  144. // DEL_ZONE_NSEC3_RECORDS: delete all NSEC3-related records from the zone
  145. "DELETE FROM nsec3 WHERE zone_id=?1",
  146. // DEL_NSEC3_RECORD: delete specified NSEC3-related records
  147. "DELETE FROM nsec3 WHERE zone_id=?1 AND hash=?2 "
  148. "AND rdtype=?3 AND rdata=?4",
  149. // ADD_ZONE: add a zone to the zones table
  150. "INSERT INTO zones (name, rdclass) VALUES (?1, ?2)", // ADD_ZONE
  151. // DELETE_ZONE: delete a zone from the zones table
  152. "DELETE FROM zones WHERE id=?1" // DELETE_ZONE
  153. };
  154. struct SQLite3Parameters {
  155. SQLite3Parameters() :
  156. db_(NULL), major_version_(-1), minor_version_(-1),
  157. in_transaction(false), updating_zone(false), updated_zone_id(-1)
  158. {
  159. for (int i = 0; i < NUM_STATEMENTS; ++i) {
  160. statements_[i] = NULL;
  161. }
  162. }
  163. // This method returns the specified ID of SQLITE3 statement. If it's
  164. // not yet prepared it internally creates a new one. This way we can
  165. // avoid preparing unnecessary statements and minimize the overhead.
  166. sqlite3_stmt*
  167. getStatement(int id) {
  168. assert(id < NUM_STATEMENTS);
  169. if (statements_[id] == NULL) {
  170. assert(db_ != NULL);
  171. sqlite3_stmt* prepared = NULL;
  172. if (sqlite3_prepare_v2(db_, text_statements[id], -1, &prepared,
  173. NULL) != SQLITE_OK) {
  174. isc_throw(SQLite3Error, "Could not prepare SQLite statement: "
  175. << text_statements[id] <<
  176. ": " << sqlite3_errmsg(db_));
  177. }
  178. statements_[id] = prepared;
  179. }
  180. return (statements_[id]);
  181. }
  182. void
  183. finalizeStatements() {
  184. for (int i = 0; i < NUM_STATEMENTS; ++i) {
  185. if (statements_[i] != NULL) {
  186. sqlite3_finalize(statements_[i]);
  187. statements_[i] = NULL;
  188. }
  189. }
  190. }
  191. sqlite3* db_;
  192. int major_version_;
  193. int minor_version_;
  194. bool in_transaction; // whether or not a transaction has been started
  195. bool updating_zone; // whether or not updating the zone
  196. int updated_zone_id; // valid only when in_transaction is true
  197. string updated_zone_origin_; // ditto, and only needed to handle NSEC3s
  198. private:
  199. // statements_ are private and must be accessed via getStatement() outside
  200. // of this structure.
  201. sqlite3_stmt* statements_[NUM_STATEMENTS];
  202. };
  203. // This is a helper class to encapsulate the code logic of executing
  204. // a specific SQLite3 statement, ensuring the corresponding prepared
  205. // statement is always reset whether the execution is completed successfully
  206. // or it results in an exception.
  207. // Note that an object of this class is intended to be used for "ephemeral"
  208. // statement, which is completed with a single "step" (normally within a
  209. // single call to an SQLite3Database method). In particular, it cannot be
  210. // used for "SELECT" variants, which generally expect multiple matching rows.
  211. //
  212. // The bindXXX methods are straightforward wrappers for the corresponding
  213. // sqlite3_bind_xxx functions that make bindings with the given parameters
  214. // on the statement maintained in this class.
  215. class StatementProcessor {
  216. public:
  217. // desc will be used on failure in the what() message of the resulting
  218. // DataSourceError exception.
  219. StatementProcessor(SQLite3Parameters& dbparameters, StatementID stmt_id,
  220. const char* desc) :
  221. dbparameters_(dbparameters), stmt_(dbparameters.getStatement(stmt_id)),
  222. desc_(desc)
  223. {
  224. sqlite3_clear_bindings(stmt_);
  225. }
  226. ~StatementProcessor() {
  227. sqlite3_reset(stmt_);
  228. }
  229. void bindInt(int index, int val) {
  230. if (sqlite3_bind_int(stmt_, index, val) != SQLITE_OK) {
  231. isc_throw(DataSourceError,
  232. "failed to bind SQLite3 parameter: " <<
  233. sqlite3_errmsg(dbparameters_.db_));
  234. }
  235. }
  236. void bindInt64(int index, sqlite3_int64 val) {
  237. if (sqlite3_bind_int64(stmt_, index, val) != SQLITE_OK) {
  238. isc_throw(DataSourceError,
  239. "failed to bind SQLite3 parameter: " <<
  240. sqlite3_errmsg(dbparameters_.db_));
  241. }
  242. }
  243. // For simplicity, we assume val is a NULL-terminated string, and the
  244. // entire non NUL characters are to be bound. The destructor parameter
  245. // is normally either SQLITE_TRANSIENT or SQLITE_STATIC.
  246. void bindText(int index, const char* val, void(*destructor)(void*)) {
  247. if (sqlite3_bind_text(stmt_, index, val, -1, destructor)
  248. != SQLITE_OK) {
  249. isc_throw(DataSourceError, "failed to bind SQLite3 parameter: " <<
  250. sqlite3_errmsg(dbparameters_.db_));
  251. }
  252. }
  253. void exec() {
  254. if (sqlite3_step(stmt_) != SQLITE_DONE) {
  255. sqlite3_reset(stmt_);
  256. isc_throw(DataSourceError, "failed to " << desc_ << ": " <<
  257. sqlite3_errmsg(dbparameters_.db_));
  258. }
  259. }
  260. private:
  261. SQLite3Parameters& dbparameters_;
  262. sqlite3_stmt* stmt_;
  263. const char* const desc_;
  264. };
  265. SQLite3Accessor::SQLite3Accessor(const std::string& filename,
  266. const string& rrclass) :
  267. dbparameters_(new SQLite3Parameters),
  268. filename_(filename),
  269. class_(rrclass),
  270. database_name_("sqlite3_" +
  271. isc::util::Filename(filename).nameAndExtension())
  272. {
  273. LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_SQLITE_NEWCONN);
  274. open(filename);
  275. }
  276. boost::shared_ptr<DatabaseAccessor>
  277. SQLite3Accessor::clone() {
  278. return (boost::shared_ptr<DatabaseAccessor>(new SQLite3Accessor(filename_,
  279. class_)));
  280. }
  281. namespace {
  282. // This is a helper class to initialize a Sqlite3 DB safely. An object of
  283. // this class encapsulates all temporary resources that are necessary for
  284. // the initialization, and release them in the destructor. Once everything
  285. // is properly initialized, the move() method moves the allocated resources
  286. // to the main object in an exception free manner. This way, the main code
  287. // for the initialization can be exception safe, and can provide the strong
  288. // exception guarantee.
  289. class Initializer {
  290. public:
  291. ~Initializer() {
  292. if (params_.db_ != NULL) {
  293. sqlite3_close(params_.db_);
  294. }
  295. }
  296. void move(SQLite3Parameters* dst) {
  297. *dst = params_;
  298. params_ = SQLite3Parameters(); // clear everything
  299. }
  300. SQLite3Parameters params_;
  301. };
  302. const char* const SCHEMA_LIST[] = {
  303. "CREATE TABLE schema_version (version INTEGER NOT NULL, "
  304. "minor INTEGER NOT NULL DEFAULT 0)",
  305. "INSERT INTO schema_version VALUES (2, 1)",
  306. "CREATE TABLE zones (id INTEGER PRIMARY KEY, "
  307. "name TEXT NOT NULL COLLATE NOCASE, "
  308. "rdclass TEXT NOT NULL COLLATE NOCASE DEFAULT 'IN', "
  309. "dnssec BOOLEAN NOT NULL DEFAULT 0)",
  310. "CREATE INDEX zones_byname ON zones (name)",
  311. "CREATE TABLE records (id INTEGER PRIMARY KEY, "
  312. "zone_id INTEGER NOT NULL, name TEXT NOT NULL COLLATE NOCASE, "
  313. "rname TEXT NOT NULL COLLATE NOCASE, ttl INTEGER NOT NULL, "
  314. "rdtype TEXT NOT NULL COLLATE NOCASE, sigtype TEXT COLLATE NOCASE, "
  315. "rdata TEXT NOT NULL)",
  316. "CREATE INDEX records_byname ON records (name)",
  317. "CREATE INDEX records_byrname ON records (rname)",
  318. // The next index is a tricky one. It's necessary for
  319. // FIND_PREVIOUS to use the index efficiently; since there's an
  320. // "inequality", the rname column must be placed later. records_byrname
  321. // may not be sufficient especially when the zone is not signed (and
  322. // defining a separate index for rdtype only doesn't work either; SQLite3
  323. // would then create a temporary B-tree for "ORDER BY").
  324. "CREATE INDEX records_bytype_and_rname ON records (rdtype, rname)",
  325. "CREATE TABLE nsec3 (id INTEGER PRIMARY KEY, zone_id INTEGER NOT NULL, "
  326. "hash TEXT NOT NULL COLLATE NOCASE, "
  327. "owner TEXT NOT NULL COLLATE NOCASE, "
  328. "ttl INTEGER NOT NULL, rdtype TEXT NOT NULL COLLATE NOCASE, "
  329. "rdata TEXT NOT NULL)",
  330. "CREATE INDEX nsec3_byhash ON nsec3 (hash)",
  331. "CREATE INDEX nsec3_byhash_and_rdtype ON nsec3 (hash, rdtype)",
  332. "CREATE TABLE diffs (id INTEGER PRIMARY KEY, "
  333. "zone_id INTEGER NOT NULL, "
  334. "version INTEGER NOT NULL, "
  335. "operation INTEGER NOT NULL, "
  336. "name TEXT NOT NULL COLLATE NOCASE, "
  337. "rrtype TEXT NOT NULL COLLATE NOCASE, "
  338. "ttl INTEGER NOT NULL, "
  339. "rdata TEXT NOT NULL)",
  340. NULL
  341. };
  342. sqlite3_stmt*
  343. prepare(sqlite3* const db, const char* const statement) {
  344. sqlite3_stmt* prepared = NULL;
  345. if (sqlite3_prepare_v2(db, statement, -1, &prepared, NULL) != SQLITE_OK) {
  346. isc_throw(SQLite3Error, "Could not prepare SQLite statement: " <<
  347. statement << ": " << sqlite3_errmsg(db));
  348. }
  349. return (prepared);
  350. }
  351. // small function to sleep for 0.1 seconds, needed when waiting for
  352. // exclusive database locks (which should only occur on startup, and only
  353. // when the database has not been created yet)
  354. void doSleep() {
  355. struct timespec req;
  356. req.tv_sec = 0;
  357. req.tv_nsec = 100000000;
  358. nanosleep(&req, NULL);
  359. }
  360. // returns the schema version if the schema version table exists
  361. // returns -1 if it does not
  362. int checkSchemaVersionElement(sqlite3* db, const char* const query) {
  363. sqlite3_stmt* prepared = NULL;
  364. // At this point in time, the database might be exclusively locked, in
  365. // which case even prepare() will return BUSY, so we may need to try a
  366. // few times
  367. for (size_t i = 0; i < 50; ++i) {
  368. int rc = sqlite3_prepare_v2(db, query, -1, &prepared, NULL);
  369. if (rc == SQLITE_ERROR) {
  370. // this is the error that is returned when the table does not
  371. // exist
  372. sqlite3_finalize(prepared);
  373. return (-1);
  374. } else if (rc == SQLITE_OK) {
  375. break;
  376. } else if (rc != SQLITE_BUSY || i == 50) {
  377. sqlite3_finalize(prepared);
  378. isc_throw(SQLite3Error, "Unable to prepare version query: "
  379. << rc << " " << sqlite3_errmsg(db));
  380. }
  381. doSleep();
  382. }
  383. if (sqlite3_step(prepared) != SQLITE_ROW) {
  384. sqlite3_finalize(prepared);
  385. isc_throw(SQLite3Error,
  386. "Unable to query version: " << sqlite3_errmsg(db));
  387. }
  388. int version = sqlite3_column_int(prepared, 0);
  389. sqlite3_finalize(prepared);
  390. return (version);
  391. }
  392. // Returns the schema major and minor version numbers in a pair.
  393. // Returns (-1, -1) if the table does not exist, (1, 0) for a V1
  394. // database, and (n, m) for any other.
  395. pair<int, int> checkSchemaVersion(sqlite3* db) {
  396. int major = checkSchemaVersionElement(db,
  397. "SELECT version FROM schema_version");
  398. if (major == -1) {
  399. return (make_pair(-1, -1));
  400. } else if (major == 1) {
  401. return (make_pair(1, 0));
  402. } else {
  403. int minor = checkSchemaVersionElement(db,
  404. "SELECT minor FROM schema_version");
  405. return (make_pair(major, minor));
  406. }
  407. }
  408. // A helper class used in createDatabase() below so we manage the one shot
  409. // transaction safely.
  410. class ScopedTransaction {
  411. public:
  412. ScopedTransaction(sqlite3* db) : db_(NULL) {
  413. // try for 5 secs (50*0.1)
  414. for (size_t i = 0; i < 50; ++i) {
  415. const int rc = sqlite3_exec(db, "BEGIN EXCLUSIVE TRANSACTION",
  416. NULL, NULL, NULL);
  417. if (rc == SQLITE_OK) {
  418. break;
  419. } else if (rc != SQLITE_BUSY || i == 50) {
  420. isc_throw(SQLite3Error, "Unable to acquire exclusive lock "
  421. "for database creation: " << sqlite3_errmsg(db));
  422. }
  423. doSleep();
  424. }
  425. // Hold the DB pointer once we have successfully acquired the lock.
  426. db_ = db;
  427. }
  428. ~ScopedTransaction() {
  429. if (db_ != NULL) {
  430. // Note: even rollback could fail in theory, but in that case
  431. // we cannot do much for safe recovery anyway. We could at least
  432. // log the event, but for now don't even bother to do that, with
  433. // the expectation that we'll soon stop creating the schema in this
  434. // module.
  435. sqlite3_exec(db_, "ROLLBACK", NULL, NULL, NULL);
  436. }
  437. }
  438. void commit() {
  439. if (sqlite3_exec(db_, "COMMIT TRANSACTION", NULL, NULL, NULL) !=
  440. SQLITE_OK) {
  441. isc_throw(SQLite3Error, "Unable to commit newly created database "
  442. "schema: " << sqlite3_errmsg(db_));
  443. }
  444. db_ = NULL;
  445. }
  446. private:
  447. sqlite3* db_;
  448. };
  449. // return db version
  450. pair<int, int>
  451. createDatabase(sqlite3* db, const std::string& name) {
  452. logger.warn(DATASRC_SQLITE_SETUP).arg(name);
  453. // try to get an exclusive lock. Once that is obtained, do the version
  454. // check *again*, just in case this process was racing another
  455. ScopedTransaction trasaction(db);
  456. pair<int, int> schema_version = checkSchemaVersion(db);
  457. if (schema_version.first == -1) {
  458. for (int i = 0; SCHEMA_LIST[i] != NULL; ++i) {
  459. if (sqlite3_exec(db, SCHEMA_LIST[i], NULL, NULL, NULL) !=
  460. SQLITE_OK) {
  461. isc_throw(SQLite3Error,
  462. "Failed to set up schema " << SCHEMA_LIST[i]);
  463. }
  464. }
  465. trasaction.commit();
  466. // Return the version. We query again to ensure that the only point
  467. // in which the current schema version is defined is in the create
  468. // statements.
  469. schema_version = checkSchemaVersion(db);
  470. }
  471. return (schema_version);
  472. }
  473. void
  474. checkAndSetupSchema(Initializer* initializer, const std::string& name) {
  475. sqlite3* const db = initializer->params_.db_;
  476. pair<int, int> schema_version = checkSchemaVersion(db);
  477. if (schema_version.first == -1) {
  478. schema_version = createDatabase(db, name);
  479. } else if (schema_version.first != SQLITE_SCHEMA_MAJOR_VERSION) {
  480. LOG_ERROR(logger, DATASRC_SQLITE_INCOMPATIBLE_VERSION)
  481. .arg(schema_version.first).arg(schema_version.second)
  482. .arg(SQLITE_SCHEMA_MAJOR_VERSION).arg(SQLITE_SCHEMA_MINOR_VERSION);
  483. isc_throw(IncompatibleDbVersion,
  484. "incompatible SQLite3 database version: " <<
  485. schema_version.first << "." << schema_version.second);
  486. } else if (schema_version.second < SQLITE_SCHEMA_MINOR_VERSION) {
  487. LOG_WARN(logger, DATASRC_SQLITE_COMPATIBLE_VERSION)
  488. .arg(schema_version.first).arg(schema_version.second)
  489. .arg(SQLITE_SCHEMA_MAJOR_VERSION).arg(SQLITE_SCHEMA_MINOR_VERSION);
  490. }
  491. initializer->params_.major_version_ = schema_version.first;
  492. initializer->params_.minor_version_ = schema_version.second;
  493. }
  494. }
  495. void
  496. SQLite3Accessor::open(const std::string& name) {
  497. LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_SQLITE_CONNOPEN).arg(name);
  498. if (dbparameters_->db_ != NULL) {
  499. // There shouldn't be a way to trigger this anyway
  500. isc_throw(DataSourceError, "Duplicate SQLite open with " << name);
  501. }
  502. Initializer initializer;
  503. if (sqlite3_open(name.c_str(), &initializer.params_.db_) != 0) {
  504. isc_throw(SQLite3Error, "Cannot open SQLite database file: " << name);
  505. }
  506. checkAndSetupSchema(&initializer, name);
  507. initializer.move(dbparameters_.get());
  508. }
  509. SQLite3Accessor::~SQLite3Accessor() {
  510. LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_SQLITE_DROPCONN);
  511. if (dbparameters_->db_ != NULL) {
  512. close();
  513. }
  514. }
  515. void
  516. SQLite3Accessor::close(void) {
  517. LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_SQLITE_CONNCLOSE);
  518. if (dbparameters_->db_ == NULL) {
  519. isc_throw(DataSourceError,
  520. "SQLite data source is being closed before open");
  521. }
  522. dbparameters_->finalizeStatements();
  523. sqlite3_close(dbparameters_->db_);
  524. dbparameters_->db_ = NULL;
  525. }
  526. std::pair<bool, int>
  527. SQLite3Accessor::getZone(const std::string& name) const {
  528. int rc;
  529. sqlite3_stmt* const stmt = dbparameters_->getStatement(ZONE);
  530. // Take the statement (simple SELECT id FROM zones WHERE...)
  531. // and prepare it (bind the parameters to it)
  532. sqlite3_reset(stmt);
  533. rc = sqlite3_bind_text(stmt, 1, name.c_str(), -1, SQLITE_STATIC);
  534. if (rc != SQLITE_OK) {
  535. isc_throw(SQLite3Error, "Could not bind " << name <<
  536. " to SQL statement (zone)");
  537. }
  538. rc = sqlite3_bind_text(stmt, 2, class_.c_str(), -1, SQLITE_STATIC);
  539. if (rc != SQLITE_OK) {
  540. isc_throw(SQLite3Error, "Could not bind " << class_ <<
  541. " to SQL statement (zone)");
  542. }
  543. // Get the data there and see if it found anything
  544. rc = sqlite3_step(stmt);
  545. if (rc == SQLITE_ROW) {
  546. const int zone_id = sqlite3_column_int(stmt, 0);
  547. sqlite3_reset(stmt);
  548. return (pair<bool, int>(true, zone_id));
  549. } else if (rc == SQLITE_DONE) {
  550. // Free resources
  551. sqlite3_reset(stmt);
  552. return (pair<bool, int>(false, 0));
  553. }
  554. sqlite3_reset(stmt);
  555. isc_throw(DataSourceError, "Unexpected failure in sqlite3_step: " <<
  556. sqlite3_errmsg(dbparameters_->db_));
  557. // Compilers might not realize isc_throw always throws
  558. return (std::pair<bool, int>(false, 0));
  559. }
  560. int
  561. SQLite3Accessor::addZone(const std::string& name) {
  562. // Transaction should have been started by the caller
  563. if (!dbparameters_->in_transaction) {
  564. isc_throw(DataSourceError, "performing addZone on SQLite3 "
  565. "data source without transaction");
  566. }
  567. StatementProcessor proc(*dbparameters_, ADD_ZONE, "add zone");
  568. // note: using TRANSIENT here, STATIC would be slightly more
  569. // efficient, but TRANSIENT is safer and performance is not
  570. // as important in this specific code path.
  571. proc.bindText(1, name.c_str(), SQLITE_TRANSIENT);
  572. proc.bindText(2, class_.c_str(), SQLITE_TRANSIENT);
  573. proc.exec();
  574. // There are tricks to getting this in one go, but it is safer
  575. // to do a new lookup (sqlite3_last_insert_rowid is unsafe
  576. // regarding threads and triggers). This requires two
  577. // statements, and is unpredictable in the case a zone is added
  578. // twice, but this method assumes the caller does not do that
  579. // anyway
  580. std::pair<bool, int> getzone_result = getZone(name);
  581. assert(getzone_result.first);
  582. return (getzone_result.second);
  583. }
  584. void
  585. SQLite3Accessor::deleteZone(int zone_id) {
  586. // Transaction should have been started by the caller
  587. if (!dbparameters_->in_transaction) {
  588. isc_throw(InvalidOperation, "performing deleteZone on SQLite3 "
  589. "data source without transaction");
  590. }
  591. StatementProcessor proc(*dbparameters_, DELETE_ZONE, "delete zone");
  592. proc.bindInt(1, zone_id);
  593. proc.exec();
  594. }
  595. namespace {
  596. // Conversion to plain char
  597. const char*
  598. convertToPlainChar(const unsigned char* ucp, sqlite3 *db) {
  599. if (ucp == NULL) {
  600. // The field can really be NULL, in which case we return an
  601. // empty string, or sqlite may have run out of memory, in
  602. // which case we raise an error
  603. if (sqlite3_errcode(db) == SQLITE_NOMEM) {
  604. isc_throw(DataSourceError,
  605. "Sqlite3 backend encountered a memory allocation "
  606. "error in sqlite3_column_text()");
  607. } else {
  608. return ("");
  609. }
  610. }
  611. const void* p = ucp;
  612. return (static_cast<const char*>(p));
  613. }
  614. }
  615. class SQLite3Accessor::Context : public DatabaseAccessor::IteratorContext {
  616. public:
  617. // Construct an iterator for all records. When constructed this
  618. // way, the getNext() call will copy all fields
  619. Context(const boost::shared_ptr<const SQLite3Accessor>& accessor, int id) :
  620. iterator_type_(ITT_ALL),
  621. accessor_(accessor),
  622. statement_(NULL),
  623. statement2_(NULL),
  624. rc_(SQLITE_OK),
  625. rc2_(SQLITE_OK),
  626. name_("")
  627. {
  628. // We create the statements now and then just keep getting data
  629. // from them.
  630. statement_ = prepare(accessor->dbparameters_->db_,
  631. text_statements[ITERATE_NSEC3]);
  632. bindZoneId(id);
  633. std::swap(statement_, statement2_);
  634. statement_ = prepare(accessor->dbparameters_->db_,
  635. text_statements[ITERATE_RECORDS]);
  636. bindZoneId(id);
  637. }
  638. // What kind of query it is - selection of the statement for DB
  639. enum QueryType {
  640. QT_ANY, // Directly for a domain
  641. QT_SUBDOMAINS, // Subdomains of a given domain
  642. QT_NSEC3 // Domain in the NSEC3 namespace (the name is is the hash,
  643. // not the whole name)
  644. };
  645. // Construct an iterator for records with a specific name. When constructed
  646. // this way, the getNext() call will copy all fields except name
  647. Context(const boost::shared_ptr<const SQLite3Accessor>& accessor, int id,
  648. const std::string& name, QueryType qtype) :
  649. iterator_type_(qtype == QT_NSEC3 ? ITT_NSEC3 : ITT_NAME),
  650. accessor_(accessor),
  651. statement_(NULL),
  652. statement2_(NULL),
  653. rc_(SQLITE_OK),
  654. rc2_(SQLITE_OK),
  655. name_(name)
  656. {
  657. // Choose the statement text depending on the query type, and
  658. // prepare a statement to get data from it.
  659. switch (qtype) {
  660. case QT_ANY:
  661. statement_ = prepare(accessor->dbparameters_->db_,
  662. text_statements[ANY]);
  663. bindZoneId(id);
  664. bindName(name_);
  665. break;
  666. case QT_SUBDOMAINS:
  667. statement_ = prepare(accessor->dbparameters_->db_,
  668. text_statements[ANY_SUB]);
  669. bindZoneId(id);
  670. // Done once, this should not be very inefficient.
  671. bindName(isc::dns::Name(name_).reverse().toText() + "%");
  672. break;
  673. case QT_NSEC3:
  674. statement_ = prepare(accessor->dbparameters_->db_,
  675. text_statements[NSEC3]);
  676. bindZoneId(id);
  677. bindName(name_);
  678. break;
  679. default:
  680. // Can Not Happen - there isn't any other type of query
  681. // and all the calls to the constructor are from this
  682. // file. Therefore no way to test it throws :-(.
  683. isc_throw(Unexpected,
  684. "Invalid qtype passed - unreachable code branch "
  685. "reached");
  686. }
  687. }
  688. bool getNext(std::string (&data)[COLUMN_COUNT]) {
  689. // If there's another row, get it
  690. // If finalize has been called (e.g. when previous getNext() got
  691. // SQLITE_DONE), directly return false
  692. while (statement_ != NULL) {
  693. rc_ = sqlite3_step(statement_);
  694. if (rc_ == SQLITE_ROW) {
  695. // For both types, we copy the first four columns
  696. copyColumn(data, TYPE_COLUMN);
  697. copyColumn(data, TTL_COLUMN);
  698. // The NSEC3 lookup does not provide the SIGTYPE, it is not
  699. // necessary and not contained in the table.
  700. if (iterator_type_ != ITT_NSEC3) {
  701. copyColumn(data, SIGTYPE_COLUMN);
  702. }
  703. copyColumn(data, RDATA_COLUMN);
  704. // Only copy Name if we are iterating over every record
  705. if (iterator_type_ == ITT_ALL) {
  706. copyColumn(data, NAME_COLUMN);
  707. }
  708. return (true);
  709. } else if (rc_ != SQLITE_DONE) {
  710. isc_throw(DataSourceError,
  711. "Unexpected failure in sqlite3_step: " <<
  712. sqlite3_errmsg(accessor_->dbparameters_->db_));
  713. }
  714. // We are done with statement_. If statement2_ has not been
  715. // used yet, try that one now.
  716. if ((statement2_ == NULL) || (rc2_ != SQLITE_OK)) {
  717. break;
  718. }
  719. std::swap(statement_, statement2_);
  720. std::swap(rc_, rc2_);
  721. }
  722. finalize();
  723. return (false);
  724. }
  725. virtual ~Context() {
  726. finalize();
  727. }
  728. private:
  729. // Depending on which constructor is called, behaviour is slightly
  730. // different. We keep track of what to do with the iterator type
  731. // See description of getNext() and the constructors
  732. enum IteratorType {
  733. ITT_ALL,
  734. ITT_NAME,
  735. ITT_NSEC3
  736. };
  737. void copyColumn(std::string (&data)[COLUMN_COUNT], int column) {
  738. data[column] = convertToPlainChar(sqlite3_column_text(statement_,
  739. column),
  740. accessor_->dbparameters_->db_);
  741. }
  742. void bindZoneId(const int zone_id) {
  743. if (sqlite3_bind_int(statement_, 1, zone_id) != SQLITE_OK) {
  744. finalize();
  745. isc_throw(SQLite3Error, "Could not bind int " << zone_id <<
  746. " to SQL statement: " <<
  747. sqlite3_errmsg(accessor_->dbparameters_->db_));
  748. }
  749. }
  750. void bindName(const std::string& name) {
  751. if (sqlite3_bind_text(statement_, 2, name.c_str(), -1,
  752. SQLITE_TRANSIENT) != SQLITE_OK) {
  753. const char* errmsg = sqlite3_errmsg(accessor_->dbparameters_->db_);
  754. finalize();
  755. isc_throw(SQLite3Error, "Could not bind text '" << name <<
  756. "' to SQL statement: " << errmsg);
  757. }
  758. }
  759. void finalize() {
  760. if (statement_ != NULL) {
  761. sqlite3_finalize(statement_);
  762. statement_ = NULL;
  763. }
  764. if (statement2_ != NULL) {
  765. sqlite3_finalize(statement2_);
  766. statement2_ = NULL;
  767. }
  768. }
  769. const IteratorType iterator_type_;
  770. boost::shared_ptr<const SQLite3Accessor> accessor_;
  771. sqlite3_stmt* statement_;
  772. sqlite3_stmt* statement2_;
  773. int rc_;
  774. int rc2_;
  775. const std::string name_;
  776. };
  777. // Methods to retrieve the various iterators
  778. DatabaseAccessor::IteratorContextPtr
  779. SQLite3Accessor::getRecords(const std::string& name, int id,
  780. bool subdomains) const
  781. {
  782. return (IteratorContextPtr(new Context(shared_from_this(), id, name,
  783. subdomains ?
  784. Context::QT_SUBDOMAINS :
  785. Context::QT_ANY)));
  786. }
  787. DatabaseAccessor::IteratorContextPtr
  788. SQLite3Accessor::getNSEC3Records(const std::string& hash, int id) const {
  789. return (IteratorContextPtr(new Context(shared_from_this(), id, hash,
  790. Context::QT_NSEC3)));
  791. }
  792. DatabaseAccessor::IteratorContextPtr
  793. SQLite3Accessor::getAllRecords(int id) const {
  794. return (IteratorContextPtr(new Context(shared_from_this(), id)));
  795. }
  796. /// \brief Difference Iterator
  797. ///
  798. /// This iterator is used to search through the differences table for the
  799. /// resouce records making up an IXFR between two versions of a zone.
  800. class SQLite3Accessor::DiffContext : public DatabaseAccessor::IteratorContext {
  801. public:
  802. /// \brief Constructor
  803. ///
  804. /// Constructs the iterator for the difference sequence. It is
  805. /// passed two parameters, the first and last versions in the difference
  806. /// sequence. Note that because of serial number rollover, it may well
  807. /// be that the start serial number is greater than the end one.
  808. ///
  809. /// \param zone_id ID of the zone (in the zone table)
  810. /// \param start Serial number of first version in difference sequence
  811. /// \param end Serial number of last version in difference sequence
  812. ///
  813. /// \exception any A number of exceptions can be expected
  814. DiffContext(const boost::shared_ptr<const SQLite3Accessor>& accessor,
  815. int zone_id, uint32_t start, uint32_t end) :
  816. accessor_(accessor),
  817. last_status_(SQLITE_ROW)
  818. {
  819. try {
  820. int low_id = findIndex(LOW_DIFF_ID, zone_id, start, DIFF_DELETE);
  821. int high_id = findIndex(HIGH_DIFF_ID, zone_id, end, DIFF_ADD);
  822. // Prepare the statement that will return data values
  823. reset(DIFF_RECS);
  824. bindInt(DIFF_RECS, 1, zone_id);
  825. bindInt(DIFF_RECS, 2, low_id);
  826. bindInt(DIFF_RECS, 3, high_id);
  827. } catch (...) {
  828. // Something wrong, clear up everything.
  829. accessor_->dbparameters_->finalizeStatements();
  830. throw;
  831. }
  832. }
  833. /// \brief Destructor
  834. virtual ~DiffContext()
  835. {}
  836. /// \brief Get Next Diff Record
  837. ///
  838. /// Returns the next difference record in the difference sequence.
  839. ///
  840. /// \param data Array of std::strings COLUMN_COUNT long. The results
  841. /// are returned in this.
  842. ///
  843. /// \return bool true if data is returned, false if not.
  844. ///
  845. /// \exception any Varied
  846. bool getNext(std::string (&data)[COLUMN_COUNT]) {
  847. if (last_status_ != SQLITE_DONE) {
  848. // Last call (if any) didn't reach end of result set, so we
  849. // can read another row from it.
  850. //
  851. // Get a pointer to the statement for brevity (this does not
  852. // transfer ownership of the statement to this class, so there is
  853. // no need to tidy up after we have finished using it).
  854. sqlite3_stmt* stmt =
  855. accessor_->dbparameters_->getStatement(DIFF_RECS);
  856. const int rc(sqlite3_step(stmt));
  857. if (rc == SQLITE_ROW) {
  858. // Copy the data across to the output array
  859. copyColumn(DIFF_RECS, data, TYPE_COLUMN);
  860. copyColumn(DIFF_RECS, data, TTL_COLUMN);
  861. copyColumn(DIFF_RECS, data, NAME_COLUMN);
  862. copyColumn(DIFF_RECS, data, RDATA_COLUMN);
  863. } else if (rc != SQLITE_DONE) {
  864. isc_throw(DataSourceError,
  865. "Unexpected failure in sqlite3_step: " <<
  866. sqlite3_errmsg(accessor_->dbparameters_->db_));
  867. }
  868. last_status_ = rc;
  869. }
  870. return (last_status_ == SQLITE_ROW);
  871. }
  872. private:
  873. /// \brief Reset prepared statement
  874. ///
  875. /// Sets up the statement so that new parameters can be attached to it and
  876. /// that it can be used to query for another difference sequence.
  877. ///
  878. /// \param stindex Index of prepared statement to which to bind
  879. void reset(int stindex) {
  880. sqlite3_stmt* stmt = accessor_->dbparameters_->getStatement(stindex);
  881. if ((sqlite3_reset(stmt) != SQLITE_OK) ||
  882. (sqlite3_clear_bindings(stmt) != SQLITE_OK)) {
  883. isc_throw(SQLite3Error, "Could not clear statement bindings in '" <<
  884. text_statements[stindex] << "': " <<
  885. sqlite3_errmsg(accessor_->dbparameters_->db_));
  886. }
  887. }
  888. /// \brief Bind Int
  889. ///
  890. /// Binds an integer to a specific variable in a prepared statement.
  891. ///
  892. /// \param stindex Index of prepared statement to which to bind
  893. /// \param varindex Index of variable to which to bind
  894. /// \param value Value of variable to bind
  895. /// \exception SQLite3Error on an error
  896. void bindInt(int stindex, int varindex, sqlite3_int64 value) {
  897. if (sqlite3_bind_int64(accessor_->dbparameters_->getStatement(stindex),
  898. varindex, value) != SQLITE_OK) {
  899. isc_throw(SQLite3Error, "Could not bind value to parameter " <<
  900. varindex << " in statement '" <<
  901. text_statements[stindex] << "': " <<
  902. sqlite3_errmsg(accessor_->dbparameters_->db_));
  903. }
  904. }
  905. ///\brief Get Single Value
  906. ///
  907. /// Executes a prepared statement (which has parameters bound to it)
  908. /// for which the result of a single value is expected.
  909. ///
  910. /// \param stindex Index of prepared statement in statement table.
  911. ///
  912. /// \return Value of SELECT.
  913. ///
  914. /// \exception TooMuchData Multiple rows returned when one expected
  915. /// \exception TooLittleData Zero rows returned when one expected
  916. /// \exception DataSourceError SQLite3-related error
  917. int getSingleValue(StatementID stindex) {
  918. // Get a pointer to the statement for brevity (does not transfer
  919. // resources)
  920. sqlite3_stmt* stmt = accessor_->dbparameters_->getStatement(stindex);
  921. // Execute the data. Should be just one result
  922. int rc = sqlite3_step(stmt);
  923. int result = -1;
  924. if (rc == SQLITE_ROW) {
  925. // Got some data, extract the value
  926. result = sqlite3_column_int(stmt, 0);
  927. rc = sqlite3_step(stmt);
  928. if (rc == SQLITE_DONE) {
  929. // All OK, exit with the value.
  930. return (result);
  931. } else if (rc == SQLITE_ROW) {
  932. isc_throw(TooMuchData, "request to return one value from "
  933. "diffs table returned multiple values");
  934. }
  935. } else if (rc == SQLITE_DONE) {
  936. // No data in the table. A bare exception with no explanation is
  937. // thrown, as it will be replaced by a more informative one by
  938. // the caller.
  939. isc_throw(TooLittleData, "");
  940. }
  941. // We get here on an error.
  942. isc_throw(DataSourceError, "could not get data from diffs table: " <<
  943. sqlite3_errmsg(accessor_->dbparameters_->db_));
  944. // Keep the compiler happy with a return value.
  945. return (result);
  946. }
  947. /// \brief Find index
  948. ///
  949. /// Executes the prepared statement locating the high or low index in
  950. /// the diffs table and returns that index.
  951. ///
  952. /// \param stmt_id Index of the prepared statement to execute
  953. /// \param zone_id ID of the zone for which the index is being sought
  954. /// \param serial Zone serial number for which an index is being sought.
  955. /// \param diff Code to delete record additions or deletions
  956. ///
  957. /// \return int ID of the row in the difss table corresponding to the
  958. /// statement.
  959. ///
  960. /// \exception TooLittleData Internal error, no result returned when one
  961. /// was expected.
  962. /// \exception NoSuchSerial Serial number not found.
  963. /// \exception NoDiffsData No data for this zone found in diffs table
  964. int findIndex(StatementID stindex, int zone_id, uint32_t serial, int diff) {
  965. // Set up the statement
  966. reset(stindex);
  967. bindInt(stindex, 1, zone_id);
  968. bindInt(stindex, 2, serial);
  969. bindInt(stindex, 3, diff);
  970. // Execute the statement
  971. int result = -1;
  972. try {
  973. result = getSingleValue(stindex);
  974. } catch (const TooLittleData&) {
  975. // No data returned but the SQL query succeeded. Only possibility
  976. // is that there is no entry in the differences table for the given
  977. // zone and version.
  978. isc_throw(NoSuchSerial, "No entry in differences table for" <<
  979. " zone ID " << zone_id << ", serial number " << serial);
  980. }
  981. return (result);
  982. }
  983. /// \brief Copy Column to Output
  984. ///
  985. /// Copies the textual data in the result set to the specified column
  986. /// in the output.
  987. ///
  988. /// \param stindex Index of prepared statement used to access data
  989. /// \param data Array of columns passed to getNext
  990. /// \param column Column of output to copy
  991. void copyColumn(StatementID stindex, std::string (&data)[COLUMN_COUNT],
  992. int column) {
  993. // Get a pointer to the statement for brevity (does not transfer
  994. // resources)
  995. sqlite3_stmt* stmt = accessor_->dbparameters_->getStatement(stindex);
  996. data[column] = convertToPlainChar(sqlite3_column_text(stmt,
  997. column),
  998. accessor_->dbparameters_->db_);
  999. }
  1000. // Attributes
  1001. boost::shared_ptr<const SQLite3Accessor> accessor_; // Accessor object
  1002. int last_status_; // Last status received from sqlite3_step
  1003. };
  1004. // ... and return the iterator
  1005. DatabaseAccessor::IteratorContextPtr
  1006. SQLite3Accessor::getDiffs(int id, uint32_t start, uint32_t end) const {
  1007. return (IteratorContextPtr(new DiffContext(shared_from_this(), id, start,
  1008. end)));
  1009. }
  1010. pair<bool, int>
  1011. SQLite3Accessor::startUpdateZone(const string& zone_name, const bool replace) {
  1012. if (dbparameters_->updating_zone) {
  1013. isc_throw(DataSourceError,
  1014. "duplicate zone update on SQLite3 data source");
  1015. }
  1016. if (dbparameters_->in_transaction) {
  1017. isc_throw(DataSourceError,
  1018. "zone update attempt in another SQLite3 transaction");
  1019. }
  1020. const pair<bool, int> zone_info(getZone(zone_name));
  1021. if (!zone_info.first) {
  1022. return (zone_info);
  1023. }
  1024. StatementProcessor(*dbparameters_, BEGIN,
  1025. "start an SQLite3 update transaction").exec();
  1026. if (replace) {
  1027. // First, clear all current data from tables.
  1028. typedef pair<StatementID, const char* const> StatementSpec;
  1029. const StatementSpec delzone_stmts[] =
  1030. { StatementSpec(DEL_ZONE_RECORDS, "delete zone records"),
  1031. StatementSpec(DEL_ZONE_NSEC3_RECORDS,
  1032. "delete zone NSEC3 records") };
  1033. try {
  1034. for (size_t i = 0;
  1035. i < sizeof(delzone_stmts) / sizeof(delzone_stmts[0]);
  1036. ++i) {
  1037. StatementProcessor delzone_proc(*dbparameters_,
  1038. delzone_stmts[i].first,
  1039. delzone_stmts[i].second);
  1040. delzone_proc.bindInt(1, zone_info.second);
  1041. delzone_proc.exec();
  1042. }
  1043. } catch (const DataSourceError&) {
  1044. // Once we start a transaction, if something unexpected happens
  1045. // we need to rollback the transaction so that a subsequent update
  1046. // is still possible with this accessor.
  1047. StatementProcessor(*dbparameters_, ROLLBACK,
  1048. "rollback an SQLite3 transaction").exec();
  1049. throw;
  1050. }
  1051. }
  1052. dbparameters_->in_transaction = true;
  1053. dbparameters_->updating_zone = true;
  1054. dbparameters_->updated_zone_id = zone_info.second;
  1055. dbparameters_->updated_zone_origin_ = zone_name;
  1056. return (zone_info);
  1057. }
  1058. void
  1059. SQLite3Accessor::startTransaction() {
  1060. if (dbparameters_->in_transaction) {
  1061. isc_throw(DataSourceError,
  1062. "duplicate transaction on SQLite3 data source");
  1063. }
  1064. StatementProcessor(*dbparameters_, BEGIN,
  1065. "start an SQLite3 transaction").exec();
  1066. dbparameters_->in_transaction = true;
  1067. }
  1068. void
  1069. SQLite3Accessor::commit() {
  1070. if (!dbparameters_->in_transaction) {
  1071. isc_throw(DataSourceError, "performing commit on SQLite3 "
  1072. "data source without transaction");
  1073. }
  1074. StatementProcessor(*dbparameters_, COMMIT,
  1075. "commit an SQLite3 transaction").exec();
  1076. dbparameters_->in_transaction = false;
  1077. dbparameters_->updating_zone = false;
  1078. dbparameters_->updated_zone_id = -1;
  1079. dbparameters_->updated_zone_origin_.clear();
  1080. }
  1081. void
  1082. SQLite3Accessor::rollback() {
  1083. if (!dbparameters_->in_transaction) {
  1084. isc_throw(DataSourceError, "performing rollback on SQLite3 "
  1085. "data source without transaction");
  1086. }
  1087. StatementProcessor(*dbparameters_, ROLLBACK,
  1088. "rollback an SQLite3 transaction").exec();
  1089. dbparameters_->in_transaction = false;
  1090. dbparameters_->updating_zone = false;
  1091. dbparameters_->updated_zone_id = -1;
  1092. dbparameters_->updated_zone_origin_.clear();
  1093. }
  1094. namespace {
  1095. // Commonly used code sequence for adding/deleting record
  1096. template <typename COLUMNS_TYPE>
  1097. void
  1098. doUpdate(SQLite3Parameters& dbparams, StatementID stmt_id,
  1099. COLUMNS_TYPE update_params, const char* exec_desc)
  1100. {
  1101. StatementProcessor proc(dbparams, stmt_id, exec_desc);
  1102. int param_id = 0;
  1103. proc.bindInt(++param_id, dbparams.updated_zone_id);
  1104. const size_t column_count =
  1105. sizeof(update_params) / sizeof(update_params[0]);
  1106. for (int i = 0; i < column_count; ++i) {
  1107. // The old sqlite3 data source API assumes NULL for an empty column.
  1108. // We need to provide compatibility at least for now.
  1109. proc.bindText(++param_id, update_params[i].empty() ? NULL :
  1110. update_params[i].c_str(), SQLITE_TRANSIENT);
  1111. }
  1112. proc.exec();
  1113. }
  1114. }
  1115. void
  1116. SQLite3Accessor::addRecordToZone(const string (&columns)[ADD_COLUMN_COUNT]) {
  1117. if (!dbparameters_->updating_zone) {
  1118. isc_throw(DataSourceError, "adding record to SQLite3 "
  1119. "data source without transaction");
  1120. }
  1121. doUpdate<const string (&)[ADD_COLUMN_COUNT]>(
  1122. *dbparameters_, ADD_RECORD, columns, "add record to zone");
  1123. }
  1124. void
  1125. SQLite3Accessor::addNSEC3RecordToZone(
  1126. const string (&columns)[ADD_NSEC3_COLUMN_COUNT])
  1127. {
  1128. if (!dbparameters_->updating_zone) {
  1129. isc_throw(DataSourceError, "adding NSEC3-related record to SQLite3 "
  1130. "data source without transaction");
  1131. }
  1132. // XXX: the current implementation of SQLite3 schema requires the 'owner'
  1133. // column, and the current implementation of getAllRecords() relies on it,
  1134. // while the addNSEC3RecordToZone interface doesn't provide it explicitly.
  1135. // We should revisit it at the design level, but for now we internally
  1136. // convert the given parameter to satisfy the internal requirements.
  1137. const string sqlite3_columns[ADD_NSEC3_COLUMN_COUNT + 1] =
  1138. { columns[ADD_NSEC3_HASH],
  1139. columns[ADD_NSEC3_HASH] + "." + dbparameters_->updated_zone_origin_,
  1140. columns[ADD_NSEC3_TTL],
  1141. columns[ADD_NSEC3_TYPE], columns[ADD_NSEC3_RDATA] };
  1142. doUpdate<const string (&)[ADD_NSEC3_COLUMN_COUNT + 1]>(
  1143. *dbparameters_, ADD_NSEC3_RECORD, sqlite3_columns,
  1144. "add NSEC3 record to zone");
  1145. }
  1146. void
  1147. SQLite3Accessor::deleteRecordInZone(const string (&params)[DEL_PARAM_COUNT]) {
  1148. if (!dbparameters_->updating_zone) {
  1149. isc_throw(DataSourceError, "deleting record in SQLite3 "
  1150. "data source without transaction");
  1151. }
  1152. doUpdate<const string (&)[DEL_PARAM_COUNT]>(
  1153. *dbparameters_, DEL_RECORD, params, "delete record from zone");
  1154. }
  1155. void
  1156. SQLite3Accessor::deleteNSEC3RecordInZone(
  1157. const string (&params)[DEL_PARAM_COUNT])
  1158. {
  1159. if (!dbparameters_->updating_zone) {
  1160. isc_throw(DataSourceError, "deleting NSEC3-related record in SQLite3 "
  1161. "data source without transaction");
  1162. }
  1163. doUpdate<const string (&)[DEL_PARAM_COUNT]>(
  1164. *dbparameters_, DEL_NSEC3_RECORD, params,
  1165. "delete NSEC3 record from zone");
  1166. }
  1167. void
  1168. SQLite3Accessor::addRecordDiff(int zone_id, uint32_t serial,
  1169. DiffOperation operation,
  1170. const std::string (&params)[DIFF_PARAM_COUNT])
  1171. {
  1172. if (!dbparameters_->updating_zone) {
  1173. isc_throw(DataSourceError, "adding record diff without update "
  1174. "transaction on " << getDBName());
  1175. }
  1176. if (zone_id != dbparameters_->updated_zone_id) {
  1177. isc_throw(DataSourceError, "bad zone ID for adding record diff on "
  1178. << getDBName() << ": " << zone_id << ", must be "
  1179. << dbparameters_->updated_zone_id);
  1180. }
  1181. StatementProcessor proc(*dbparameters_, ADD_RECORD_DIFF,
  1182. "add record diff");
  1183. int param_id = 0;
  1184. proc.bindInt(++param_id, zone_id);
  1185. proc.bindInt64(++param_id, serial);
  1186. proc.bindInt(++param_id, operation);
  1187. for (int i = 0; i < DIFF_PARAM_COUNT; ++i) {
  1188. proc.bindText(++param_id, params[i].c_str(), SQLITE_TRANSIENT);
  1189. }
  1190. proc.exec();
  1191. }
  1192. std::string
  1193. SQLite3Accessor::findPreviousName(int zone_id, const std::string& rname)
  1194. const
  1195. {
  1196. sqlite3_stmt* const stmt = dbparameters_->getStatement(FIND_PREVIOUS);
  1197. sqlite3_reset(stmt);
  1198. sqlite3_clear_bindings(stmt);
  1199. if (sqlite3_bind_int(stmt, 1, zone_id) != SQLITE_OK) {
  1200. isc_throw(SQLite3Error, "Could not bind zone ID " << zone_id <<
  1201. " to SQL statement (find previous): " <<
  1202. sqlite3_errmsg(dbparameters_->db_));
  1203. }
  1204. if (sqlite3_bind_text(stmt, 2, rname.c_str(), -1, SQLITE_STATIC) !=
  1205. SQLITE_OK) {
  1206. isc_throw(SQLite3Error, "Could not bind name " << rname <<
  1207. " to SQL statement (find previous): " <<
  1208. sqlite3_errmsg(dbparameters_->db_));
  1209. }
  1210. std::string result;
  1211. const int rc = sqlite3_step(stmt);
  1212. if (rc == SQLITE_ROW) {
  1213. // We found it
  1214. result = convertToPlainChar(sqlite3_column_text(stmt, 0),
  1215. dbparameters_->db_);
  1216. }
  1217. sqlite3_reset(stmt);
  1218. if (rc == SQLITE_DONE) {
  1219. // No NSEC records here, this DB doesn't support DNSSEC or
  1220. // we asked before the apex
  1221. isc_throw(isc::NotImplemented, "The zone doesn't support DNSSEC or "
  1222. "query before apex");
  1223. }
  1224. if (rc != SQLITE_ROW && rc != SQLITE_DONE) {
  1225. // Some kind of error
  1226. isc_throw(SQLite3Error, "Could not get data for previous name");
  1227. }
  1228. return (result);
  1229. }
  1230. std::string
  1231. SQLite3Accessor::findPreviousNSEC3Hash(int zone_id, const std::string& hash)
  1232. const
  1233. {
  1234. sqlite3_stmt* const stmt = dbparameters_->getStatement(NSEC3_PREVIOUS);
  1235. sqlite3_reset(stmt);
  1236. sqlite3_clear_bindings(stmt);
  1237. if (sqlite3_bind_int(stmt, 1, zone_id) != SQLITE_OK) {
  1238. isc_throw(SQLite3Error, "Could not bind zone ID " << zone_id <<
  1239. " to SQL statement (find previous NSEC3): " <<
  1240. sqlite3_errmsg(dbparameters_->db_));
  1241. }
  1242. if (sqlite3_bind_text(stmt, 2, hash.c_str(), -1, SQLITE_STATIC) !=
  1243. SQLITE_OK) {
  1244. isc_throw(SQLite3Error, "Could not bind hash " << hash <<
  1245. " to SQL statement (find previous NSEC3): " <<
  1246. sqlite3_errmsg(dbparameters_->db_));
  1247. }
  1248. std::string result;
  1249. const int rc = sqlite3_step(stmt);
  1250. if (rc == SQLITE_ROW) {
  1251. // We found it
  1252. result = convertToPlainChar(sqlite3_column_text(stmt, 0),
  1253. dbparameters_->db_);
  1254. }
  1255. sqlite3_reset(stmt);
  1256. if (rc != SQLITE_ROW && rc != SQLITE_DONE) {
  1257. // Some kind of error
  1258. isc_throw(SQLite3Error, "Could not get data for previous hash");
  1259. }
  1260. if (rc == SQLITE_DONE) {
  1261. // No NSEC3 records before this hash. This means we should wrap
  1262. // around and take the last one.
  1263. sqlite3_stmt* const stmt = dbparameters_->getStatement(NSEC3_LAST);
  1264. sqlite3_reset(stmt);
  1265. sqlite3_clear_bindings(stmt);
  1266. if (sqlite3_bind_int(stmt, 1, zone_id) != SQLITE_OK) {
  1267. isc_throw(SQLite3Error, "Could not bind zone ID " << zone_id <<
  1268. " to SQL statement (find last NSEC3): " <<
  1269. sqlite3_errmsg(dbparameters_->db_));
  1270. }
  1271. const int rc = sqlite3_step(stmt);
  1272. if (rc == SQLITE_ROW) {
  1273. // We found it
  1274. result = convertToPlainChar(sqlite3_column_text(stmt, 0),
  1275. dbparameters_->db_);
  1276. }
  1277. sqlite3_reset(stmt);
  1278. if (rc != SQLITE_ROW && rc != SQLITE_DONE) {
  1279. // Some kind of error
  1280. isc_throw(SQLite3Error, "Could not get data for last hash");
  1281. }
  1282. if (rc == SQLITE_DONE) {
  1283. // No NSEC3 at all in the zone. Well, bad luck, but you should not
  1284. // have asked in the first place.
  1285. isc_throw(DataSourceError, "No NSEC3 in this zone");
  1286. }
  1287. }
  1288. return (result);
  1289. }
  1290. } // end of namespace datasrc
  1291. } // end of namespace isc