sqlite3_accessor.cc 54 KB

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