Commit 86448664 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[master] Merge branch 'trac324new2' with fixing conflict for

	src/lib/python/isc/notify/tests/testdata/test.sqlite3
parents 49c83cc4 16b92d01
noinst_SCRIPTS = sqlite3-difftbl-check.py
# We're going to abuse install-data-local for a pre-install check.
# This is to be considered a short term hack and is expected to be removed
# in a near future version.
install-data-local:
$(PYTHON) sqlite3-difftbl-check.py \
$(localstatedir)/$(PACKAGE)/zone.sqlite3
if test -e $(localstatedir)/$(PACKAGE)/zone.sqlite3; then \
$(SHELL) $(top_builddir)/src/bin/dbutil/run_dbutil.sh --check \
$(localstatedir)/$(PACKAGE)/zone.sqlite3 || \
(echo "\nSQLite3 DB file schema version is old. " \
"Please run: " \
"$(abs_top_builddir)/src/bin/dbutil/run_dbutil.sh --upgrade " \
"$(localstatedir)/$(PACKAGE)/zone.sqlite3"; exit 1) \
fi
#!@PYTHON@
# Copyright (C) 2011 Internet Systems Consortium.
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import os, sqlite3, sys
from optparse import OptionParser
usage = 'usage: %prog [options] db_file'
parser = OptionParser(usage=usage)
parser.add_option("-u", "--upgrade", action="store_true",
dest="upgrade", default=False,
help="Upgrade the database file [default: %default]")
(options, args) = parser.parse_args()
if len(args) == 0:
parser.error('missing argument')
db_file = args[0]
# If the file doesn't exist, there's nothing to do
if not os.path.exists(db_file):
sys.exit(0)
conn = sqlite3.connect(db_file)
cur = conn.cursor()
try:
# This can be anything that works iff the "diffs" table exists
cur.execute('SELECT name FROM diffs DESC LIMIT 1')
except sqlite3.OperationalError as ex:
# If it fails with 'no such table', create a new one or fail with
# warning depending on the --upgrade command line option.
if str(ex) == 'no such table: diffs':
if options.upgrade:
cur.execute('CREATE TABLE diffs (id INTEGER PRIMARY KEY, ' +
'zone_id INTEGER NOT NULL, ' +
'version INTEGER NOT NULL, ' +
'operation INTEGER NOT NULL, ' +
'name STRING NOT NULL COLLATE NOCASE, ' +
'rrtype STRING NOT NULL COLLATE NOCASE, ' +
'ttl INTEGER NOT NULL, rdata STRING NOT NULL)')
else:
sys.stdout.write('Found an older version of SQLite3 DB file: ' +
db_file + '\n' + "Perform '" + os.getcwd() +
"/sqlite3-difftbl-check.py --upgrade " +
db_file + "'\n" +
'before continuing install.\n')
sys.exit(1)
conn.close()
......@@ -1139,7 +1139,6 @@ AC_CONFIG_FILES([Makefile
tests/tools/perfdhcp/Makefile
])
AC_OUTPUT([doc/version.ent
compatcheck/sqlite3-difftbl-check.py
src/bin/cfgmgr/b10-cfgmgr.py
src/bin/cfgmgr/tests/b10-cfgmgr_test.py
src/bin/cmdctl/cmdctl.py
......
......@@ -378,10 +378,7 @@ def get_latest_version():
This is the 'to' version held in the last element of the upgrades list
"""
# Temporarily hardcoded to return 1 as the schema version, until
# #324 is merged.
#return UPGRADES[-1]['to']
return (1, 0)
return UPGRADES[-1]['to']
def get_version(db):
......
......@@ -359,22 +359,19 @@ check_version $testdata/old_v1.sqlite3 "V1.0"
check_no_backup $tempfile $backupfile
rm -f $tempfile $backupfile
# Temporarily disabled until #324 is merged
#echo "5.2. Database is an old V1 database - upgrade"
#upgrade_ok_test $testdata/old_v1.sqlite3 $backupfile
#rm -f $tempfile $backupfile
echo "5.2. Database is an old V1 database - upgrade"
upgrade_ok_test $testdata/old_v1.sqlite3 $backupfile
rm -f $tempfile $backupfile
# Temporarily disabled until #324 is merged
#echo "6.1. Database is new V1 database - check"
#check_version $testdata/new_v1.sqlite3 "V1.0"
#check_no_backup $tempfile $backupfile
#rm -f $tempfile $backupfile
echo "6.1. Database is new V1 database - check"
check_version $testdata/new_v1.sqlite3 "V1.0"
check_no_backup $tempfile $backupfile
rm -f $tempfile $backupfile
# Temporarily disabled until #324 is merged
#echo "6.2. Database is a new V1 database - upgrade"
#upgrade_ok_test $testdata/new_v1.sqlite3 $backupfile
#rm -f $tempfile $backupfile
echo "6.2. Database is a new V1 database - upgrade"
upgrade_ok_test $testdata/new_v1.sqlite3 $backupfile
rm -f $tempfile $backupfile
echo "7.1. Database is V2.0 database - check"
......@@ -405,10 +402,9 @@ upgrade_fail_test $testdata/too_many_version.sqlite3 $backupfile
rm -f $tempfile $backupfile
# Temporarily disabled until #324 is merged
#echo "10.0. Upgrade corrupt database"
#upgrade_fail_test $testdata/corrupt.sqlite3 $backupfile
#rm -f $tempfile $backupfile
echo "10.0. Upgrade corrupt database"
upgrade_fail_test $testdata/corrupt.sqlite3 $backupfile
rm -f $tempfile $backupfile
echo "11. Record count test"
......@@ -447,15 +443,14 @@ copy_file $testdata/old_v1.sqlite3 $tempfile
passzero $?
rm -f $tempfile $backupfile
# Temporarily disabled until #324 is merged
#echo "13.3 Interactive prompt - yes"
#copy_file $testdata/old_v1.sqlite3 $tempfile
#../run_dbutil.sh --upgrade $tempfile << .
#Yes
#.
#passzero $?
#check_version $tempfile "V2.0"
#rm -f $tempfile $backupfile
echo "13.3 Interactive prompt - yes"
copy_file $testdata/old_v1.sqlite3 $tempfile
../run_dbutil.sh --upgrade $tempfile << .
Yes
.
passzero $?
check_version $tempfile "V2.0"
rm -f $tempfile $backupfile
echo "13.4 Interactive prompt - no"
copy_file $testdata/old_v1.sqlite3 $tempfile
......
......@@ -20,6 +20,7 @@ endif
for pytest in $(PYTESTS) ; do \
echo Running test: $$pytest ; \
$(LIBRARY_PATH_PLACEHOLDER) \
TESTDATAOBJDIR=$(abs_top_builddir)/src/bin/zonemgr/tests/ \
B10_FROM_BUILD=$(abs_top_builddir) \
PYTHONPATH=$(COMMON_PYTHON_PATH):$(abs_top_builddir)/src/bin/zonemgr:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/xfr/.libs \
$(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \
......
......@@ -35,6 +35,8 @@ LOWERBOUND_RETRY = 5
REFRESH_JITTER = 0.10
RELOAD_JITTER = 0.75
TEST_SQLITE3_DBFILE = os.getenv("TESTDATAOBJDIR") + '/initdb.file'
class ZonemgrTestException(Exception):
pass
......@@ -57,7 +59,7 @@ class FakeCCSession(isc.config.ConfigData, MockModuleCCSession):
def get_remote_config_value(self, module_name, identifier):
if module_name == "Auth" and identifier == "database_file":
return "initdb.file", False
return TEST_SQLITE3_DBFILE, False
else:
return "unknown", False
......@@ -81,7 +83,7 @@ class MyZonemgrRefresh(ZonemgrRefresh):
return None
sqlite3_ds.get_zone_soa = get_zone_soa
ZonemgrRefresh.__init__(self, MySession(), "initdb.file",
ZonemgrRefresh.__init__(self, MySession(), TEST_SQLITE3_DBFILE,
self._slave_socket, FakeCCSession())
current_time = time.time()
self._zonemgr_refresh_info = {
......@@ -99,11 +101,18 @@ class MyZonemgrRefresh(ZonemgrRefresh):
class TestZonemgrRefresh(unittest.TestCase):
def setUp(self):
if os.path.exists(TEST_SQLITE3_DBFILE):
os.unlink(TEST_SQLITE3_DBFILE)
self.stderr_backup = sys.stderr
sys.stderr = open(os.devnull, 'w')
self.zone_refresh = MyZonemgrRefresh()
self.cc_session = FakeCCSession()
def tearDown(self):
if os.path.exists(TEST_SQLITE3_DBFILE):
os.unlink(TEST_SQLITE3_DBFILE)
sys.stderr = self.stderr_backup
def test_random_jitter(self):
max = 100025.120
jitter = 0
......@@ -602,13 +611,10 @@ class TestZonemgrRefresh(unittest.TestCase):
self.zone_refresh.update_config_data,
config, self.cc_session)
def tearDown(self):
sys.stderr= self.stderr_backup
class MyZonemgr(Zonemgr):
def __init__(self):
self._db_file = "initdb.file"
self._db_file = TEST_SQLITE3_DBFILE
self._zone_refresh = None
self._shutdown_event = threading.Event()
self._cc = MySession()
......@@ -628,8 +634,14 @@ class MyZonemgr(Zonemgr):
class TestZonemgr(unittest.TestCase):
def setUp(self):
if os.path.exists(TEST_SQLITE3_DBFILE):
os.unlink(TEST_SQLITE3_DBFILE)
self.zonemgr = MyZonemgr()
def tearDown(self):
if os.path.exists(TEST_SQLITE3_DBFILE):
os.unlink(TEST_SQLITE3_DBFILE)
def test_config_handler(self):
config_data1 = {
"lowerbound_refresh" : 60,
......@@ -650,8 +662,8 @@ class TestZonemgr(unittest.TestCase):
self.zonemgr.config_handler(config_data3)
self.assertEqual(0.5, self.zonemgr._config_data.get("refresh_jitter"))
# The zone doesn't exist in database, simply skip loading soa for it and log an warning
self.zonemgr._zone_refresh = ZonemgrRefresh(None, "initdb.file", None,
FakeCCSession())
self.zonemgr._zone_refresh = ZonemgrRefresh(None, TEST_SQLITE3_DBFILE,
None, FakeCCSession())
config_data1["secondary_zones"] = [{"name": "nonexistent.example",
"class": "IN"}]
self.assertEqual(self.zonemgr.config_handler(config_data1),
......@@ -663,7 +675,7 @@ class TestZonemgr(unittest.TestCase):
self.assertEqual(0.1, self.zonemgr._config_data.get("refresh_jitter"))
def test_get_db_file(self):
self.assertEqual("initdb.file", self.zonemgr.get_db_file())
self.assertEqual(TEST_SQLITE3_DBFILE, self.zonemgr.get_db_file())
def test_parse_cmd_params(self):
params1 = {"zone_name" : "example.com.", "zone_class" : "CH", "master" : "127.0.0.1"}
......@@ -691,9 +703,6 @@ class TestZonemgr(unittest.TestCase):
self.zonemgr.run()
self.assertTrue(self.zonemgr._module_cc.stopped)
def tearDown(self):
pass
if __name__== "__main__":
isc.log.resetUnitTestRootLogger()
unittest.main()
......@@ -634,6 +634,17 @@ enough information for it. The code is 1 for error, 2 for not implemented.
% DATASRC_SQLITE_CLOSE closing SQLite database
Debug information. The SQLite data source is closing the database file.
% DATASRC_SQLITE_COMPATIBLE_VERSION database schema V%1.%2 not up to date (expecting V%3.%4) but is compatible
The version of the SQLite3 database schema used to hold the zone data
is not the latest one - the current version of BIND 10 was written
with a later schema version in mind. However, the database is
compatible with the current version of BIND 10, and BIND 10 will run
without any problems.
Consult the release notes for your version of BIND 10. Depending on
the changes made to the database schema, it is possible that improved
performance could result if the database were upgraded.
% DATASRC_SQLITE_CONNCLOSE Closing sqlite database
The database file is no longer needed and is being closed.
......@@ -701,6 +712,14 @@ source.
The SQLite data source was asked to provide a NSEC3 record for given zone.
But it doesn't contain that zone.
% DATASRC_SQLITE_INCOMPATIBLE_VERSION database schema V%1.%2 incompatible with version (V%3.%4) expected
The version of the SQLite3 database schema used to hold the zone data
is incompatible with the version expected by BIND 10. As a result,
BIND 10 is unable to run using the database file as the data source.
The database should be updated using the means described in the BIND
10 documentation.
% DATASRC_SQLITE_NEWCONN SQLite3Database is being initialized
A wrapper object to hold database connection is being initialized.
......
......@@ -15,8 +15,11 @@
#include <sqlite3.h>
#include <string>
#include <utility>
#include <vector>
#include <exceptions/exceptions.h>
#include <datasrc/sqlite3_accessor.h>
#include <datasrc/logger.h>
#include <datasrc/data_source.h>
......@@ -27,7 +30,20 @@
using namespace std;
using namespace isc::data;
#define SQLITE_SCHEMA_VERSION 1
namespace {
// Expected schema. The major version must match else there is an error. If
// the minor version of the database is less than this, a warning is output.
//
// It is assumed that a program written to run on m.n of the database will run
// with a database version m.p, where p is any number. However, if p < n,
// we assume that the database structure was upgraded for some reason, and that
// some advantage may result if the database is upgraded. Conversely, if p > n,
// The database is at a later version than the program was written for and the
// program may not be taking advantage of features (possibly performance
// improvements) added to the database.
const int SQLITE_SCHEMA_MAJOR_VERSION = 2;
const int SQLITE_SCHEMA_MINOR_VERSION = 0;
}
namespace isc {
namespace datasrc {
......@@ -125,8 +141,8 @@ const char* const text_statements[NUM_STATEMENTS] = {
struct SQLite3Parameters {
SQLite3Parameters() :
db_(NULL), version_(-1), in_transaction(false), updating_zone(false),
updated_zone_id(-1)
db_(NULL), major_version_(-1), minor_version_(-1),
in_transaction(false), updating_zone(false), updated_zone_id(-1)
{
for (int i = 0; i < NUM_STATEMENTS; ++i) {
statements_[i] = NULL;
......@@ -164,7 +180,8 @@ struct SQLite3Parameters {
}
sqlite3* db_;
int version_;
int major_version_;
int minor_version_;
bool in_transaction; // whether or not a transaction has been started
bool updating_zone; // whether or not updating the zone
int updated_zone_id; // valid only when in_transaction is true
......@@ -255,34 +272,42 @@ public:
};
const char* const SCHEMA_LIST[] = {
"CREATE TABLE schema_version (version INTEGER NOT NULL)",
"INSERT INTO schema_version VALUES (1)",
"CREATE TABLE schema_version (version INTEGER NOT NULL, "
"minor INTEGER NOT NULL DEFAULT 0)",
"INSERT INTO schema_version VALUES (2, 0)",
"CREATE TABLE zones (id INTEGER PRIMARY KEY, "
"name STRING NOT NULL COLLATE NOCASE, "
"rdclass STRING NOT NULL COLLATE NOCASE DEFAULT 'IN', "
"name TEXT NOT NULL COLLATE NOCASE, "
"rdclass TEXT NOT NULL COLLATE NOCASE DEFAULT 'IN', "
"dnssec BOOLEAN NOT NULL DEFAULT 0)",
"CREATE INDEX zones_byname ON zones (name)",
"CREATE TABLE records (id INTEGER PRIMARY KEY, "
"zone_id INTEGER NOT NULL, name STRING NOT NULL COLLATE NOCASE, "
"rname STRING NOT NULL COLLATE NOCASE, ttl INTEGER NOT NULL, "
"rdtype STRING NOT NULL COLLATE NOCASE, sigtype STRING COLLATE NOCASE, "
"rdata STRING NOT NULL)",
"zone_id INTEGER NOT NULL, name TEXT NOT NULL COLLATE NOCASE, "
"rname TEXT NOT NULL COLLATE NOCASE, ttl INTEGER NOT NULL, "
"rdtype TEXT NOT NULL COLLATE NOCASE, sigtype TEXT COLLATE NOCASE, "
"rdata TEXT NOT NULL)",
"CREATE INDEX records_byname ON records (name)",
"CREATE INDEX records_byrname ON records (rname)",
// The next index is a tricky one. It's necessary for
// FIND_PREVIOUS to use the index efficiently; since there's an
// "inequality", the rname column must be placed later. records_byrname
// may not be sufficient especially when the zone is not signed (and
// defining a separate index for rdtype only doesn't work either; SQLite3
// would then create a temporary B-tree for "ORDER BY").
"CREATE INDEX records_bytype_and_rname ON records (rdtype, rname)",
"CREATE TABLE nsec3 (id INTEGER PRIMARY KEY, zone_id INTEGER NOT NULL, "
"hash STRING NOT NULL COLLATE NOCASE, "
"owner STRING NOT NULL COLLATE NOCASE, "
"ttl INTEGER NOT NULL, rdtype STRING NOT NULL COLLATE NOCASE, "
"rdata STRING NOT NULL)",
"hash TEXT NOT NULL COLLATE NOCASE, "
"owner TEXT NOT NULL COLLATE NOCASE, "
"ttl INTEGER NOT NULL, rdtype TEXT NOT NULL COLLATE NOCASE, "
"rdata TEXT NOT NULL)",
"CREATE INDEX nsec3_byhash ON nsec3 (hash)",
"CREATE TABLE diffs (id INTEGER PRIMARY KEY, "
"zone_id INTEGER NOT NULL, "
"version INTEGER NOT NULL, "
"operation INTEGER NOT NULL, "
"name STRING NOT NULL COLLATE NOCASE, "
"rrtype STRING NOT NULL COLLATE NOCASE, "
"name TEXT NOT NULL COLLATE NOCASE, "
"rrtype TEXT NOT NULL COLLATE NOCASE, "
"ttl INTEGER NOT NULL, "
"rdata STRING NOT NULL)",
"rdata TEXT NOT NULL)",
NULL
};
......@@ -308,14 +333,13 @@ void doSleep() {
// returns the schema version if the schema version table exists
// returns -1 if it does not
int checkSchemaVersion(sqlite3* db) {
int checkSchemaVersionElement(sqlite3* db, const char* const query) {
sqlite3_stmt* prepared = NULL;
// At this point in time, the database might be exclusively locked, in
// which case even prepare() will return BUSY, so we may need to try a
// few times
for (size_t i = 0; i < 50; ++i) {
int rc = sqlite3_prepare_v2(db, "SELECT version FROM schema_version",
-1, &prepared, NULL);
int rc = sqlite3_prepare_v2(db, query, -1, &prepared, NULL);
if (rc == SQLITE_ERROR) {
// this is the error that is returned when the table does not
// exist
......@@ -337,50 +361,116 @@ int checkSchemaVersion(sqlite3* db) {
return (version);
}
// Returns the schema major and minor version numbers in a pair.
// Returns (-1, -1) if the table does not exist, (1, 0) for a V1
// database, and (n, m) for any other.
pair<int, int> checkSchemaVersion(sqlite3* db) {
int major = checkSchemaVersionElement(db,
"SELECT version FROM schema_version");
if (major == -1) {
return (make_pair(-1, -1));
} else if (major == 1) {
return (make_pair(1, 0));
} else {
int minor = checkSchemaVersionElement(db,
"SELECT minor FROM schema_version");
return (make_pair(major, minor));
}
}
// A helper class used in createDatabase() below so we manage the one shot
// transaction safely.
class ScopedTransaction {
public:
ScopedTransaction(sqlite3* db) : db_(NULL) {
// try for 5 secs (50*0.1)
for (size_t i = 0; i < 50; ++i) {
const int rc = sqlite3_exec(db, "BEGIN EXCLUSIVE TRANSACTION",
NULL, NULL, NULL);
if (rc == SQLITE_OK) {
break;
} else if (rc != SQLITE_BUSY || i == 50) {
isc_throw(SQLite3Error, "Unable to acquire exclusive lock "
"for database creation: " << sqlite3_errmsg(db));
}
doSleep();
}
// Hold the DB pointer once we have successfully acquired the lock.
db_ = db;
}
~ScopedTransaction() {
if (db_ != NULL) {
// Note: even rollback could fail in theory, but in that case
// we cannot do much for safe recovery anyway. We could at least
// log the event, but for now don't even bother to do that, with
// the expectation that we'll soon stop creating the schema in this
// module.
sqlite3_exec(db_, "ROLLBACK", NULL, NULL, NULL);
}
}
void commit() {
if (sqlite3_exec(db_, "COMMIT TRANSACTION", NULL, NULL, NULL) !=
SQLITE_OK) {
isc_throw(SQLite3Error, "Unable to commit newly created database "
"schema: " << sqlite3_errmsg(db_));
}
db_ = NULL;
}
private:
sqlite3* db_;
};
// return db version
int create_database(sqlite3* db) {
pair<int, int>
createDatabase(sqlite3* db) {
logger.info(DATASRC_SQLITE_SETUP);
// try to get an exclusive lock. Once that is obtained, do the version
// check *again*, just in case this process was racing another
//
// try for 5 secs (50*0.1)
int rc;
logger.info(DATASRC_SQLITE_SETUP);
for (size_t i = 0; i < 50; ++i) {
rc = sqlite3_exec(db, "BEGIN EXCLUSIVE TRANSACTION", NULL, NULL,
NULL);
if (rc == SQLITE_OK) {
break;
} else if (rc != SQLITE_BUSY || i == 50) {
isc_throw(SQLite3Error, "Unable to acquire exclusive lock "
"for database creation: " << sqlite3_errmsg(db));
}
doSleep();
}
int schema_version = checkSchemaVersion(db);
if (schema_version == -1) {
ScopedTransaction trasaction(db);
pair<int, int> schema_version = checkSchemaVersion(db);
if (schema_version.first == -1) {
for (int i = 0; SCHEMA_LIST[i] != NULL; ++i) {
if (sqlite3_exec(db, SCHEMA_LIST[i], NULL, NULL, NULL) !=
SQLITE_OK) {
isc_throw(SQLite3Error,
"Failed to set up schema " << SCHEMA_LIST[i]);
"Failed to set up schema " << SCHEMA_LIST[i]);
}
}
sqlite3_exec(db, "COMMIT TRANSACTION", NULL, NULL, NULL);
return (SQLITE_SCHEMA_VERSION);
} else {
return (schema_version);
trasaction.commit();
// Return the version. We query again to ensure that the only point
// in which the current schema version is defined is in the create
// statements.
schema_version = checkSchemaVersion(db);
}
return (schema_version);
}
void
checkAndSetupSchema(Initializer* initializer) {
sqlite3* const db = initializer->params_.db_;
int schema_version = checkSchemaVersion(db);
if (schema_version != SQLITE_SCHEMA_VERSION) {
schema_version = create_database(db);
}
initializer->params_.version_ = schema_version;
pair<int, int> schema_version = checkSchemaVersion(db);
if (schema_version.first == -1) {
schema_version = createDatabase(db);
} else if (schema_version.first != SQLITE_SCHEMA_MAJOR_VERSION) {
LOG_ERROR(logger, DATASRC_SQLITE_INCOMPATIBLE_VERSION)
.arg(schema_version.first).arg(schema_version.second)
.arg(SQLITE_SCHEMA_MAJOR_VERSION).arg(SQLITE_SCHEMA_MINOR_VERSION);
isc_throw(IncompatibleDbVersion,
"incompatible SQLite3 database version: " <<
schema_version.first << "." << schema_version.second);
} else if (schema_version.second < SQLITE_SCHEMA_MINOR_VERSION) {
LOG_WARN(logger, DATASRC_SQLITE_COMPATIBLE_VERSION)
.arg(schema_version.first).arg(schema_version.second)
.arg(SQLITE_SCHEMA_MAJOR_VERSION).arg(SQLITE_SCHEMA_MINOR_VERSION);
}
initializer->params_.major_version_ = schema_version.first;
initializer->params_.minor_version_ = schema_version.second;
}
}
......
......@@ -47,6 +47,12 @@ public:
DataSourceError(file, line, what) {}
};
class IncompatibleDbVersion : public Exception {
public:
IncompatibleDbVersion(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) {}
};
/**
* \brief Too Much Data
*
......
......@@ -14,19 +14,33 @@
#include <string>
#include <sstream>
#include <utility>
#include <sqlite3.h>