diff --git a/DOC/RESTORE_FROM_SQLITE.md b/DOC/RESTORE_FROM_SQLITE.md index dba031a6..6fb39686 100644 --- a/DOC/RESTORE_FROM_SQLITE.md +++ b/DOC/RESTORE_FROM_SQLITE.md @@ -31,32 +31,6 @@ database restored successfully | 1 | fiona | +----+-------+ ``` -### HTTP - _Be sure to set the Content-type header as shown._ - -```bash -~ $ sqlite3 restore.sqlite -SQLite version 3.14.1 2016-08-11 18:53:32 -Enter ".help" for usage hints. -sqlite> CREATE TABLE foo (id integer not null primary key, name text); -sqlite> INSERT INTO "foo" VALUES(1,'fiona'); -sqlite> -~ $ echo '.dump' | sqlite3 restore.sqlite > restore.dump # Convert SQLite database file to set of SQL commands. -~ $ curl -XPOST localhost:4001/db/load -H "Content-type: text/plain" --data-binary @restore.dump -``` - -Let's connect to the node, and check that the data has been loaded correctly. -```bash -$ rqlite -127.0.0.1:4001> SELECT * FROM foo -+----+-------+ -| id | name | -+----+-------+ -| 1 | fiona | -+----+-------+ -``` - -**Note that you must convert the SQLite file (in the above examples the file named `restore.sqlite`) to the list of SQL commands**. You cannot restore using the actual SQLite database file. ## Caveats The behavior of the restore operation when data already exists on the cluster is undefined -- you should only restore to a cluster that has no data, or a brand-new cluster. Also, please **note that SQLite dump files normally contain a command to disable Foreign Key constraints**. If you are running with Foreign Key Constraints enabled, and wish to re-enable this, this is the one time you should explicitly re-enable those constraints via the following `curl` command: diff --git a/system_test/full_system_test.py b/system_test/full_system_test.py index 38fdcad9..92ec34ed 100644 --- a/system_test/full_system_test.py +++ b/system_test/full_system_test.py @@ -468,12 +468,18 @@ class Node(object): raise_for_status(r) fd.write(r.content) - def restore(self, file): + def restore(self, file, fmt=None): # This is the one API that doesn't expect JSON. - conn = sqlite3.connect(file) - r = requests.post(self._load_url(), data='\n'.join(conn.iterdump())) - raise_for_status(r) - conn.close() + if fmt != "binary": + conn = sqlite3.connect(file) + r = requests.post(self._load_url(fmt), data='\n'.join(conn.iterdump())) + raise_for_status(r) + conn.close() + else: + with open(file, 'rb') as f: + data = f.read() + r = requests.post(self._load_url(fmt), data=data, headers={'Content-Type': 'application/octet-stream'}) + raise_for_status(r) return r.json() def redirect_addr(self): @@ -1287,6 +1293,14 @@ class TestEndToEndBackupRestore(unittest.TestCase): j = self.node1.query('SELECT * FROM foo') self.assertEqual(j, d_("{'results': [{'values': [[1, 'fiona']], 'types': ['integer', 'text'], 'columns': ['id', 'name']}]}")) + self.node2 = Node(RQLITED_PATH, '1') + self.node2.start() + self.node2.wait_for_leader() + j = self.node2.restore(self.db_file, fmt='binary') + self.assertEqual(j, d_("{'results': []}")) + j = self.node2.query('SELECT * FROM foo') + self.assertEqual(j, d_("{'results': [{'values': [[1, 'fiona']], 'types': ['integer', 'text'], 'columns': ['id', 'name']}]}")) + def tearDown(self): if hasattr(self, 'node0'): deprovision_node(self.node0)