mirror of
https://github.com/DBD-SQLite/DBD-SQLite
synced 2025-06-07 06:08:38 -04:00
Merge branch 'backup_between_dbhs'
This commit is contained in:
commit
45f473b587
5 changed files with 168 additions and 1 deletions
22
SQLite.xs
22
SQLite.xs
|
@ -259,6 +259,28 @@ backup_to_file(dbh, filename)
|
|||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
static int
|
||||
backup_from_dbh(dbh, from)
|
||||
SV *dbh
|
||||
SV *from
|
||||
ALIAS:
|
||||
DBD::SQLite::db::sqlite_backup_from_dbh = 1
|
||||
CODE:
|
||||
RETVAL = sqlite_db_backup_from_dbh(aTHX_ dbh, from);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
static int
|
||||
backup_to_dbh(dbh, to)
|
||||
SV *dbh
|
||||
SV *to
|
||||
ALIAS:
|
||||
DBD::SQLite::db::sqlite_backup_to_dbh = 1
|
||||
CODE:
|
||||
RETVAL = sqlite_db_backup_to_dbh(aTHX_ dbh, to);
|
||||
OUTPUT:
|
||||
RETVAL
|
||||
|
||||
HV*
|
||||
table_column_metadata(dbh, dbname, tablename, columnname)
|
||||
SV* dbh
|
||||
|
|
86
dbdimp.c
86
dbdimp.c
|
@ -2615,6 +2615,49 @@ sqlite_db_backup_from_file(pTHX_ SV *dbh, char *filename)
|
|||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
sqlite_db_backup_from_dbh(pTHX_ SV *dbh, SV *from)
|
||||
{
|
||||
D_imp_dbh(dbh);
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3006011
|
||||
int rc;
|
||||
sqlite3_backup *pBackup;
|
||||
|
||||
imp_dbh_t *imp_dbh_from = (imp_dbh_t *)DBIh_COM(from);
|
||||
|
||||
if (!DBIc_ACTIVE(imp_dbh)) {
|
||||
sqlite_error(dbh, -2, "attempt to backup from file on inactive database handle");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!DBIc_ACTIVE(imp_dbh_from)) {
|
||||
sqlite_error(dbh, -2, "attempt to backup from inactive database handle");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
croak_if_db_is_null();
|
||||
|
||||
/* COMPAT: sqlite3_backup_* are only available for 3006011 or newer */
|
||||
pBackup = sqlite3_backup_init(imp_dbh->db, "main", imp_dbh_from->db, "main");
|
||||
if (pBackup) {
|
||||
(void)sqlite3_backup_step(pBackup, -1);
|
||||
(void)sqlite3_backup_finish(pBackup);
|
||||
}
|
||||
rc = sqlite3_errcode(imp_dbh->db);
|
||||
|
||||
if ( rc != SQLITE_OK ) {
|
||||
sqlite_error(dbh, rc, form("sqlite_backup_from_file failed with error %s", sqlite3_errmsg(imp_dbh->db)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
sqlite_error(dbh, SQLITE_ERROR, form("backup feature requires SQLite 3.6.11 and newer"));
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Accesses the SQLite Online Backup API, and copies the currently loaded
|
||||
* database into the passed filename.
|
||||
* Usual usage of this would be when you're operating on the :memory:
|
||||
|
@ -2663,6 +2706,49 @@ sqlite_db_backup_to_file(pTHX_ SV *dbh, char *filename)
|
|||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
sqlite_db_backup_to_dbh(pTHX_ SV *dbh, SV *to)
|
||||
{
|
||||
D_imp_dbh(dbh);
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3006011
|
||||
int rc;
|
||||
sqlite3_backup *pBackup;
|
||||
|
||||
imp_dbh_t *imp_dbh_to = (imp_dbh_t *)DBIh_COM(to);
|
||||
|
||||
if (!DBIc_ACTIVE(imp_dbh)) {
|
||||
sqlite_error(dbh, -2, "attempt to backup to file on inactive database handle");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!DBIc_ACTIVE(imp_dbh_to)) {
|
||||
sqlite_error(dbh, -2, "attempt to backup to inactive database handle");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
croak_if_db_is_null();
|
||||
|
||||
/* COMPAT: sqlite3_backup_* are only available for 3006011 or newer */
|
||||
pBackup = sqlite3_backup_init(imp_dbh_to->db, "main", imp_dbh->db, "main");
|
||||
if (pBackup) {
|
||||
(void)sqlite3_backup_step(pBackup, -1);
|
||||
(void)sqlite3_backup_finish(pBackup);
|
||||
}
|
||||
rc = sqlite3_errcode(imp_dbh_to->db);
|
||||
|
||||
if ( rc != SQLITE_OK ) {
|
||||
sqlite_error(dbh, rc, form("sqlite_backup_to_file failed with error %s", sqlite3_errmsg(imp_dbh->db)));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
sqlite_error(dbh, SQLITE_ERROR, form("backup feature requires SQLite 3.6.11 and newer"));
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
sqlite_db_limit(pTHX_ SV *dbh, int id, int new_value)
|
||||
{
|
||||
|
|
2
dbdimp.h
2
dbdimp.h
|
@ -117,6 +117,8 @@ int sqlite_bind_col( SV *sth, imp_sth_t *imp_sth, SV *col, SV *ref, IV sql_type,
|
|||
int sqlite_db_busy_timeout (pTHX_ SV *dbh, SV *timeout );
|
||||
int sqlite_db_backup_from_file(pTHX_ SV *dbh, char *filename);
|
||||
int sqlite_db_backup_to_file(pTHX_ SV *dbh, char *filename);
|
||||
int sqlite_db_backup_from_dbh(pTHX_ SV *dbh, SV *from);
|
||||
int sqlite_db_backup_to_dbh(pTHX_ SV *dbh, SV *to);
|
||||
void sqlite_db_collation_needed(pTHX_ SV *dbh, SV *callback );
|
||||
SV* sqlite_db_commit_hook( pTHX_ SV *dbh, SV *hook );
|
||||
SV* sqlite_db_rollback_hook( pTHX_ SV *dbh, SV *hook );
|
||||
|
|
|
@ -47,6 +47,8 @@ sub driver {
|
|||
DBD::SQLite::db->install_method('sqlite_set_authorizer');
|
||||
DBD::SQLite::db->install_method('sqlite_backup_from_file');
|
||||
DBD::SQLite::db->install_method('sqlite_backup_to_file');
|
||||
DBD::SQLite::db->install_method('sqlite_backup_from_dbh');
|
||||
DBD::SQLite::db->install_method('sqlite_backup_to_dbh');
|
||||
DBD::SQLite::db->install_method('sqlite_enable_load_extension');
|
||||
DBD::SQLite::db->install_method('sqlite_load_extension');
|
||||
DBD::SQLite::db->install_method('sqlite_register_fts3_perl_tokenizer');
|
||||
|
@ -2206,6 +2208,19 @@ special :memory: database, and you wish to populate it from an existing DB.
|
|||
This method accesses the SQLite Online Backup API, and will take a backup of
|
||||
the currently connected database, and write it out to the named file.
|
||||
|
||||
=head2 $dbh->sqlite_backup_from_dbh( $another_dbh )
|
||||
|
||||
This method accesses the SQLite Online Backup API, and will take a backup of
|
||||
the database for the passed handle, copying it to, and overwriting, your current database
|
||||
connection. This can be particularly handy if your current connection is to the
|
||||
special :memory: database, and you wish to populate it from an existing DB.
|
||||
You can use this to backup from an in-memory database to another in-memory database.
|
||||
|
||||
=head2 $dbh->sqlite_backup_to_dbh( $another_dbh )
|
||||
|
||||
This method accesses the SQLite Online Backup API, and will take a backup of
|
||||
the currently connected database, and write it out to the passed database handle.
|
||||
|
||||
=head2 $dbh->sqlite_enable_load_extension( $bool )
|
||||
|
||||
Calling this method with a true value enables loading (external)
|
||||
|
|
|
@ -12,7 +12,7 @@ BEGIN { requires_sqlite('3.6.11') }
|
|||
use Test::NoWarnings;
|
||||
use DBI;
|
||||
|
||||
plan tests => 6 * @CALL_FUNCS + 1;
|
||||
plan tests => 11 * @CALL_FUNCS + 1;
|
||||
|
||||
foreach my $call_func (@CALL_FUNCS) {
|
||||
# Connect to the test db and add some stuff:
|
||||
|
@ -69,3 +69,45 @@ foreach my $call_func (@CALL_FUNCS) {
|
|||
|
||||
unlink $dbfile;
|
||||
}
|
||||
|
||||
foreach my $call_func (@CALL_FUNCS) {
|
||||
# Connect to the test db and add some stuff:
|
||||
my $foo = connect_ok( dbfile => ':memory:', RaiseError => 1 );
|
||||
$foo->do(
|
||||
'CREATE TABLE online_backup_test( id INTEGER PRIMARY KEY, foo INTEGER )'
|
||||
);
|
||||
$foo->do("INSERT INTO online_backup_test (foo) VALUES ($$)");
|
||||
|
||||
my $dbh = DBI->connect(
|
||||
'dbi:SQLite:dbname=:memory:',
|
||||
undef, undef,
|
||||
{ RaiseError => 1 }
|
||||
);
|
||||
|
||||
ok($dbh->$call_func($foo, 'backup_from_dbh'));
|
||||
|
||||
{
|
||||
my ($count) = $dbh->selectrow_array(
|
||||
"SELECT count(foo) FROM online_backup_test WHERE foo=$$"
|
||||
);
|
||||
is($count, 1, "Found our process ID in backed-up table");
|
||||
}
|
||||
|
||||
# Add more data then attempt to copy it back to file:
|
||||
$dbh->do(
|
||||
'CREATE TABLE online_backup_test2 ( id INTEGER PRIMARY KEY, foo INTEGER )'
|
||||
);
|
||||
$dbh->do("INSERT INTO online_backup_test2 (foo) VALUES ($$)");
|
||||
|
||||
# backup to dbh (foo):
|
||||
ok($dbh->$call_func($foo, 'backup_to_dbh'));
|
||||
|
||||
$dbh->disconnect;
|
||||
|
||||
my ($count) = $foo->selectrow_array(
|
||||
"SELECT count(foo) FROM online_backup_test2 WHERE foo=$$"
|
||||
);
|
||||
is($count, 1, "Found our process ID in table back on disk");
|
||||
|
||||
$foo->disconnect;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue