[svn] commit: r767 - in /branches/each-ds/src/lib/auth/cpp: data_source_sqlite3.cc data_source_sqlite3.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Feb 9 08:04:21 UTC 2010
Author: mgraff
Date: Tue Feb 9 08:04:21 2010
New Revision: 767
Log:
rework class to not use an internal helper class, as it only complicates things
Modified:
branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc
branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.h
Modified: branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc (original)
+++ branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc Tue Feb 9 08:04:21 2010
@@ -7,309 +7,249 @@
#include <iostream>
using namespace std;
+using namespace isc::dns::rdata;
namespace isc {
namespace dns {
-class SQLITE3 {
-public:
- //
- // Create a new database, or open an existing one.
- //
- SQLITE3() {
- db = NULL;
- database_version = -1;
- }
-
- //
- // Close the database and free items up.
- //
- ~SQLITE3() {
- close();
- }
-
- void close(void) {
- if (db == NULL) {
- return;
+//
+// Prepare a statement. Can call release() or sqlite3_finalize()
+// directly.
+//
+sqlite3_stmt* Sqlite3DataSrc::prepare(const char *statement) {
+ int rc;
+ sqlite3_stmt *prepared = NULL;
+
+ rc = sqlite3_prepare_v2(db, statement, strlen(statement) + 1,
+ &prepared, NULL);
+ if (rc != SQLITE_OK) {
+ throw("could not prepare");
+ }
+ return (prepared);
+}
+
+//
+// Release memory associated with a prepared query.
+//
+void Sqlite3DataSrc::release(sqlite3_stmt* prepared) {
+ sqlite3_finalize(prepared);
+}
+
+//
+// Get the database schema version.
+//
+int Sqlite3DataSrc::getVersion(void) {
+ if (database_version == -1) {
+ loadVersion();
+ }
+ return (database_version);
+}
+
+//
+// Find the exact zone match. Return -1 if not found, or the zone's
+// ID if found. This will always be >= 0 if found.
+//
+int Sqlite3DataSrc::hasExactZone(const char *name) const {
+ int rc;
+ sqlite3_reset(q_zone);
+ rc = sqlite3_bind_text(q_zone, 1, name, -1, SQLITE_STATIC);
+ if (rc != SQLITE_OK) {
+ throw("Could not bind");
+ }
+ rc = sqlite3_step(q_zone);
+ if (rc == SQLITE_ROW) {
+ return (sqlite3_column_int(q_zone, 0));
+ } else {
+ return (-1);
+ }
+}
+
+
+int Sqlite3DataSrc::findRecords(const Name& name, const RRType& rdtype, RRsetList& target) const {
+ int rc;
+ const char *c_name = name.toText().c_str();
+ const char *c_rdtype = rdtype.toText().c_str();
+
+ int zone_id = findClosest(c_name, NULL);
+ if (zone_id < 0) {
+ return (0);
+ }
+
+ sqlite3_reset(q_record);
+ rc = sqlite3_bind_int(q_record, 1, zone_id);
+ if (rc != SQLITE_OK) {
+ throw("Could not bind 1");
+ }
+ rc = sqlite3_bind_text(q_record, 2, c_name, -1, SQLITE_STATIC);
+ if (rc != SQLITE_OK) {
+ throw("Could not bind 2");
+ }
+ rc = sqlite3_bind_text(q_record, 3, c_rdtype, -1, SQLITE_STATIC);
+ if (rc != SQLITE_OK) {
+ throw("Could not bind 3");
+ }
+
+ RRsetPtr rrset = RRsetPtr(new RRset(name, RRClass("IN"), RRType("TXT"),
+ RRTTL(3600)));
+
+ // loop
+ int rows = 0;
+ do {
+ rc = sqlite3_step(q_record);
+ if (rc == SQLITE_ROW) {
+ rows++;
+
+ const unsigned char *type = sqlite3_column_text(q_record, 0);
+ int ttl = sqlite3_column_int(q_record, 1);
+ const unsigned char *sigtype = sqlite3_column_text(q_record, 2);
+ const unsigned char *rdata = sqlite3_column_text(q_record, 3);
+
+ if (sigtype == NULL) {
+ rrset->addRdata(generic::TXT((const char *) rdata));
+ }
+
+ cout << "Found:"
+ << name << " "
+ << ttl << " "
+ << type << " ";
+ if (sigtype != NULL) {
+ cout << sigtype << " ";
+ }
+ cout << rdata << endl;
}
-
- if (q_zone != NULL) {
- release(q_zone);
- q_zone = NULL;
+ } while (rc == SQLITE_ROW);
+
+ if (rows > 0) {
+ target.push_back(rrset);
+ }
+
+ return (rows);
+}
+
+//
+// Search for the closest enclosing zone. Will return -1 if not found,
+// >= 0 if found. If position is not NULL, it will be filled in with the
+// longest match found.
+//
+int Sqlite3DataSrc::findClosest(const char *name, const char **position) const {
+ int rc;
+ const char *current = name;
+
+ while (*current != 0) {
+ rc = hasExactZone(current);
+ if (rc >= 0) {
+ if (position != NULL) {
+ *position = current;
+ }
+ return (rc);
}
-
- if (q_record) {
- release(q_record);
- q_record = NULL;
+ while (*current != '.' && *current != 0) {
+ current++;
}
-
- sqlite3_close(db);
-
- db = NULL;
- }
-
- //
- // Open the database.
- //
- void open(string name) {
- database_name = name;
-
- rc = sqlite3_open(database_name.c_str(), &db);
- if (rc) {
- std::cerr << "open database: " << sqlite3_errmsg(db) << "\n";
- sqlite3_close(db);
- throw("Cannot open database");
+ if (*current == '.') {
+ *current++;
}
-
- checkAndSetupSchema();
- }
-
- //
- // Prepare a statement. Can call release() or sqlite3_finalize()
- // directly.
- //
- sqlite3_stmt* prepare(const char *statement) {
- sqlite3_stmt *prepared = NULL;
- rc = sqlite3_prepare_v2(db, statement, strlen(statement) + 1,
- &prepared, NULL);
- if (rc != SQLITE_OK) {
- throw("could not prepare");
- }
- return (prepared);
- }
-
- //
- // Release memory associated with a prepared query.
- //
- void release(sqlite3_stmt* prepared) {
- sqlite3_finalize(prepared);
- }
-
- //
- // Get the database schema version.
- //
- int getVersion(void) {
- if (database_version == -1) {
- loadVersion();
- }
- return (database_version);
- }
-
- //
- // Find the exact zone match. Return -1 if not found, or the zone's
- // ID if found. This will always be >= 0 if found.
- //
- int hasExactZone(const char *name) {
- sqlite3_reset(q_zone);
- rc = sqlite3_bind_text(q_zone, 1, name, -1, SQLITE_STATIC);
- if (rc != SQLITE_OK) {
- throw("Could not bind");
- }
- rc = sqlite3_step(q_zone);
- if (rc == SQLITE_ROW) {
- return (sqlite3_column_int(q_zone, 0));
- } else {
- return (-1);
- }
- }
-
-
- int findRecords(const Name& name, const RRType& rdtype, RRsetList& target) {
- using namespace isc::dns::rdata;
- const char *c_name = name.toText().c_str();
- const char *c_rdtype = rdtype.toText().c_str();
-
- int zone_id = findClosest(c_name, NULL);
- if (zone_id < 0) {
- return (0);
- }
-
- sqlite3_reset(q_record);
- rc = sqlite3_bind_int(q_record, 1, zone_id);
- if (rc != SQLITE_OK) {
- throw("Could not bind 1");
- }
- rc = sqlite3_bind_text(q_record, 2, c_name, -1, SQLITE_STATIC);
- if (rc != SQLITE_OK) {
- throw("Could not bind 2");
- }
- rc = sqlite3_bind_text(q_record, 3, c_rdtype, -1, SQLITE_STATIC);
- if (rc != SQLITE_OK) {
- throw("Could not bind 3");
- }
-
- RRsetPtr rrset = RRsetPtr(new RRset(name, RRClass("IN"), RRType("TXT"),
- RRTTL(3600)));
-
- // loop
- int rows = 0;
- do {
- rc = sqlite3_step(q_record);
- if (rc == SQLITE_ROW) {
- rows++;
-
- const unsigned char *type = sqlite3_column_text(q_record, 0);
- int ttl = sqlite3_column_int(q_record, 1);
- const unsigned char *sigtype = sqlite3_column_text(q_record, 2);
- const unsigned char *rdata = sqlite3_column_text(q_record, 3);
-
- if (sigtype == NULL) {
- rrset->addRdata(generic::TXT((const char *) rdata));
- }
-
- cout << "Found:"
- << name << " "
- << ttl << " "
- << type << " ";
- if (sigtype != NULL) {
- cout << sigtype << " ";
- }
- cout << rdata << endl;
- }
- } while (rc == SQLITE_ROW);
-
- if (rows > 0) {
- target.push_back(rrset);
- }
-
- return (rows);
- }
-
- //
- // Search for the closest enclosing zone. Will return -1 if not found,
- // >= 0 if found. If position is not NULL, it will be filled in with the
- // longest match found.
- //
- int findClosest(const char *name, const char **position) {
- const char *current = name;
-
- while (*current != 0) {
- rc = hasExactZone(current);
- if (rc >= 0) {
- if (position != NULL) {
- *position = current;
- }
- return (rc);
- }
- while (*current != '.' && *current != 0) {
- current++;
- }
- if (*current == '.') {
- *current++;
- }
- }
-
- return (-1);
- }
-
-private:
- void loadVersion(void) {
- const char *q = "SELECT version FROM schema_version";
- sqlite3_stmt *prepared = prepare(q);
- rc = sqlite3_step(prepared);
- if (rc != SQLITE_ROW) {
- throw("failed to find a row in schema_version table");
- }
- database_version = sqlite3_column_int(prepared, 0);
- release(prepared);
- }
-
- void setupPreparedStatements(void) {
- const char *q_zone_str = "SELECT id FROM zones WHERE name=?1";
- const char *q_record_str = "SELECT rdtype, ttl, sigtype, rdata FROM records WHERE zone_id=?1 AND name=?2 AND ((rdtype=?3 OR sigtype=?3) OR (rdtype='CNAME' OR sigtype='CNAME'))";
-
- try {
- q_zone = prepare(q_zone_str);
- } catch (const char *e) {
- cout << e << endl << q_zone_str << endl;
- cout << sqlite3_errmsg(db) << endl;
- throw(e);
- }
- try {
- q_record = prepare(q_record_str);
- } catch (const char *e) {
- cout << e << endl << q_record_str << endl;
- cout << sqlite3_errmsg(db) << endl;
- throw(e);
- }
- }
-
- void execSetupQuery(const char *query) {
- rc = sqlite3_exec(db, query, NULL, NULL, NULL);
- if (rc != SQLITE_OK) {
- throw(query);
- }
- }
-
- void checkAndSetupSchema(void) {
- try {
- loadVersion();
- setupPreparedStatements();
- cout << "Loaded existing schema" << endl;
- } catch(...) {
- execSetupQuery("CREATE TABLE schema_version ("
- "version INTEGER NOT NULL)");
- execSetupQuery("INSERT INTO schema_version VALUES (1)");
- execSetupQuery("CREATE TABLE zones ("
- "id INTEGER PRIMARY KEY, "
- "name STRING NOT NULL, "
- "rdclass STRING NOT NULL DEFAULT 'IN', "
- "dnssec BOOLEAN NOT NULL DEFAULT 0)");
- execSetupQuery("CREATE TABLE records ("
- "id INTEGER PRIMARY KEY, "
- "zone_id INTEGER NOT NULL, "
- "name STRING NOT NULL, "
- "rname STRING NOT NULL, "
- "ttl INTEGER NOT NULL, "
- "rdtype STRING NOT NULL, "
- "sigtype STRING, "
- "rdata STRING NOT NULL)");
- execSetupQuery("CREATE INDEX records_byname ON records (name)");
- execSetupQuery("CREATE INDEX records_byrname ON records (rname)");
- execSetupQuery("CREATE INDEX zones_byname ON zones (name)");
-
- setupPreparedStatements();
- cout << "Created new file and schema" << endl;
- }
- }
-
- sqlite3 *db;
- int rc;
- string database_name;
- int database_version;
-
- //
- // prepared statements
- //
- sqlite3_stmt *q_zone;
- sqlite3_stmt *q_record;
-};
-
-Sqlite3DataSrc::Sqlite3DataSrc() {
-}
-
-Sqlite3DataSrc::~Sqlite3DataSrc() {
+ }
+
+ return (-1);
+}
+
+void Sqlite3DataSrc::loadVersion(void) {
+ int rc;
+
+ const char *q = "SELECT version FROM schema_version";
+ sqlite3_stmt *prepared = prepare(q);
+ rc = sqlite3_step(prepared);
+ if (rc != SQLITE_ROW) {
+ throw("failed to find a row in schema_version table");
+ }
+ database_version = sqlite3_column_int(prepared, 0);
+ release(prepared);
+}
+
+void Sqlite3DataSrc::setupPreparedStatements(void) {
+ const char *q_zone_str = "SELECT id FROM zones WHERE name=?1";
+ const char *q_record_str = "SELECT rdtype, ttl, sigtype, rdata FROM records WHERE zone_id=?1 AND name=?2 AND ((rdtype=?3 OR sigtype=?3) OR (rdtype='CNAME' OR sigtype='CNAME'))";
+
+ try {
+ q_zone = prepare(q_zone_str);
+ } catch (const char *e) {
+ cout << e << endl << q_zone_str << endl;
+ cout << sqlite3_errmsg(db) << endl;
+ throw(e);
+ }
+ try {
+ q_record = prepare(q_record_str);
+ } catch (const char *e) {
+ cout << e << endl << q_record_str << endl;
+ cout << sqlite3_errmsg(db) << endl;
+ throw(e);
+ }
+}
+
+void Sqlite3DataSrc::execSetupQuery(const char *query) {
+ int rc;
+
+ rc = sqlite3_exec(db, query, NULL, NULL, NULL);
+ if (rc != SQLITE_OK) {
+ throw(query);
+ }
+}
+
+void Sqlite3DataSrc::checkAndSetupSchema(void) {
+ try {
+ loadVersion();
+ setupPreparedStatements();
+ cout << "Loaded existing schema" << endl;
+ } catch(...) {
+ execSetupQuery("CREATE TABLE schema_version ("
+ "version INTEGER NOT NULL)");
+ execSetupQuery("INSERT INTO schema_version VALUES (1)");
+ execSetupQuery("CREATE TABLE zones ("
+ "id INTEGER PRIMARY KEY, "
+ "name STRING NOT NULL, "
+ "rdclass STRING NOT NULL DEFAULT 'IN', "
+ "dnssec BOOLEAN NOT NULL DEFAULT 0)");
+ execSetupQuery("CREATE TABLE records ("
+ "id INTEGER PRIMARY KEY, "
+ "zone_id INTEGER NOT NULL, "
+ "name STRING NOT NULL, "
+ "rname STRING NOT NULL, "
+ "ttl INTEGER NOT NULL, "
+ "rdtype STRING NOT NULL, "
+ "sigtype STRING, "
+ "rdata STRING NOT NULL)");
+ execSetupQuery("CREATE INDEX records_byname ON records (name)");
+ execSetupQuery("CREATE INDEX records_byrname ON records (rname)");
+ execSetupQuery("CREATE INDEX zones_byname ON zones (name)");
+
+ setupPreparedStatements();
+ cout << "Created new file and schema" << endl;
+ }
+}
+
+Sqlite3DataSrc::Sqlite3DataSrc()
+{
+ db = NULL;
+ database_version = -1;
+}
+
+Sqlite3DataSrc::~Sqlite3DataSrc()
+{
+ close();
}
DSResult
-Sqlite3DataSrc::init() {
- sql = new SQLITE3();
-
+Sqlite3DataSrc::init()
+{
try {
- sql->open("/tmp/zone.sqlite3");
-
- cout << "Schema version: " << sql->getVersion() << endl;
+ open("/tmp/zone.sqlite3");
+
+ cout << "Schema version: " << getVersion() << endl;
} catch (const char *e) {
cout << e << endl;
}
- return (SUCCESS);
-}
-
-DSResult
-Sqlite3DataSrc::close() {
- sql->close();
- sql = NULL;
return (SUCCESS);
}
@@ -319,13 +259,10 @@
const char *position;
- cout << "XXXXXXXXXXXXXX Looking for " << qname << endl;
- int ret = sql->findClosest(qname.toText().c_str(), &position);
+ int ret = findClosest(qname.toText().c_str(), &position);
if (ret == -1) {
return;
}
-
- cout << "XXXXXXXXXXXXXX Found name " << qname << " position " << position;
match.update(*this, Name(position));
}
@@ -336,7 +273,7 @@
const RRType& qtype,
RRsetList& target) const
{
- int rows = sql->findRecords(qname, qtype, target);
+ int rows = findRecords(qname, qtype, target);
if (rows == 0) {
return (NAME_NOT_FOUND);
} else {
@@ -353,60 +290,48 @@
return (findRRset(qname, qclass, qtype, target));
}
-#if 0
-int main(int argc, char** argv) {
- if (argc != 2) {
- cerr << "Usage: " << argv[0]
- << " DATABASE" << endl;
- exit(1);
- }
-
- SQLITE3 sql(argv[1]);
- try {
- sql.open();
-
- cout << "Schema version: " << sql.getVersion() << endl;
- } catch (const char *e) {
- cout << e << endl;
- }
-
- cout << "Has zone: example.com? " << sql.hasExactZone("example.com") << endl;
-
- const char *best_match = NULL;
- const char *target = "www.sql1.example.com";
- int has_zone = sql.findClosest(target, &best_match);
- if (has_zone >= 0) {
- cout << "Has zone or parent for " << target << endl;
- cout << " " << best_match << endl;
- } else {
- cout << "Does not have zone or parent for " << target << endl;
- }
-
- best_match = NULL;
- target = "www.sql2.example.com";
- has_zone = sql.findClosest(target, &best_match);
- if (has_zone >= 0) {
- cout << "Has zone or parent for " << target << endl;
- cout << " " << best_match << endl;
- } else {
- cout << "Does not have zone or parent for " << target << endl;
- }
-
- best_match = NULL;
- target = "www.example.com";
- has_zone = sql.findClosest(target, &best_match);
- if (has_zone >= 0) {
- cout << "Has zone or parent for " << target << endl;
- cout << " " << best_match << endl;
- } else {
- cout << "Does not have zone or parent for " << target << endl;
- }
-
- sql.findRecords("example.com", "example.com", "NS");
- sql.findRecords("example.com", "www.example.com", "A");
- sql.findRecords("example.com", "foo.example.com", "A");
-}
-#endif // main
-
-}
-}
+//
+// Open the database.
+//
+void
+Sqlite3DataSrc::open(const string& name)
+{
+ int rc;
+
+ database_name = name;
+
+ rc = sqlite3_open(database_name.c_str(), &db);
+ if (rc) {
+ cerr << "open database: " << sqlite3_errmsg(db) << "\n";
+ sqlite3_close(db);
+ throw("Cannot open database");
+ }
+
+ checkAndSetupSchema();
+}
+
+DSResult
+Sqlite3DataSrc::close(void)
+{
+ if (db == NULL) {
+ return SUCCESS;
+ }
+
+ if (q_zone != NULL) {
+ release(q_zone);
+ q_zone = NULL;
+ }
+
+ if (q_record) {
+ release(q_record);
+ q_record = NULL;
+ }
+
+ sqlite3_close(db);
+
+ db = NULL;
+ return SUCCESS;
+}
+
+}
+}
Modified: branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.h
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.h (original)
+++ branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.h Tue Feb 9 08:04:21 2010
@@ -24,30 +24,40 @@
namespace isc {
namespace dns {
-class SQLITE3;
-
class Sqlite3DataSrc : public DataSrc {
public:
Sqlite3DataSrc();
- ~Sqlite3DataSrc();
+ virtual ~Sqlite3DataSrc();
- void findClosestEnclosure(NameMatch& match) const;
+ virtual void findClosestEnclosure(NameMatch& match) const;
- DSResult findRRset(const Name& qname,
+ virtual DSResult findRRset(const Name& qname,
const RRClass& qclass,
const RRType& qtype,
RRsetList& target, RRsetList& sigs) const;
- DSResult findRRset(const Name& qname,
+ virtual DSResult findRRset(const Name& qname,
const RRClass& qclass,
const RRType& qtype,
RRsetList& target) const;
- DSResult init();
- DSResult close();
+ virtual DSResult init();
+ virtual DSResult close();
private:
- SQLITE3* sql;
+ void open(const std::string& name);
+ sqlite3_stmt* prepare(const char *statement);
+ void release(sqlite3_stmt* prepared);
+ int getVersion(void);
+ int hasExactZone(const char *name) const;
+ int findRecords(const Name& name, const RRType& rdtype, RRsetList& target) const;
+ int findClosest(const char *name, const char **position) const;
+ void loadVersion(void);
+ void setupPreparedStatements(void);
+ void execSetupQuery(const char *query);
+ void checkAndSetupSchema(void);
+
+ sqlite3 *db;
std::string database_name;
int database_version;
More information about the bind10-changes
mailing list