DBD-SQLite
view release on metacpan or search on metacpan
1.61_04 2018-12-22
- Added sqlite_db_config method and new constants for it
- Added sqlite_defensive option to disallow dangerous SQLite features
- Exposed some of the hidden extended result codes
1.61_03 2018-12-19
- Upgraded SQLite to 3.26.0, which reportedly has a security fix
1.61_02 2018-12-01
- Added sqlite_backup_from_dbh/sqlite_backup_to_dbh methods
- Introduced sqlite_prefer_numeric_type database handle attribute
that changes the value of TYPE statement handle attribute
from an array of string to an array of integer, as an experimental
feature. Setting this may break your applications.
- Changed preferred bugtracker
1.61_01 2018-12-01
- Added ability to configure SQLITE_MAX_LENGT with environmental
variable (Roy Storey)
- Added sqlite_limit database handle method to change run-time limits
t/23_nulls.t
t/24_numrows.t
t/25_chopblanks.t
t/26_commit.t
t/27_metadata.t
t/28_schemachange.t
t/30_auto_rollback.t
t/31_bind_weird_number_param.t
t/32_inactive_error.t
t/33_non_latin_path.t
t/34_online_backup.t
t/35_table_info.t
t/36_hooks.t
t/37_regexp.t
t/38_empty_statement.t
t/39_foreign_keys.t
t/40_multiple_statements.t
t/41_placeholders.t
t/42_primary_key_info.t
t/43_fts3.t
t/44_rtree.t
$database
is the name of the database ("main", "temp", etc.) if
applicable.
$trigger_or_view
is the name of the inner-most trigger or view that is
responsible for the access attempt, or "undef" if this access
attempt is directly from top-level SQL code.
$dbh->sqlite_backup_from_file( $filename )
This method accesses the SQLite Online Backup API, and will take a
backup of the named database file, 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.
$dbh->sqlite_backup_to_file( $filename )
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.
$dbh->sqlite_enable_load_extension( $bool )
Calling this method with a true value enables loading (external)
SQLite3 extensions. After the call, you can load extensions like
this:
$dbh->sqlite_enable_load_extension(1);
$sth = $dbh->prepare("select load_extension('libsqlitefunctions.so')")
or die "Cannot prepare: " . $dbh->errstr();
SV *dbh
SV *timeout
ALIAS:
DBD::SQLite::db::sqlite_busy_timeout = 1
CODE:
RETVAL = sqlite_db_busy_timeout(aTHX_ dbh, timeout );
OUTPUT:
RETVAL
static int
backup_from_file(dbh, filename)
SV *dbh
char *filename
ALIAS:
DBD::SQLite::db::sqlite_backup_from_file = 1
CODE:
RETVAL = sqlite_db_backup_from_file(aTHX_ dbh, filename);
OUTPUT:
RETVAL
static int
backup_to_file(dbh, filename)
SV *dbh
char *filename
ALIAS:
DBD::SQLite::db::sqlite_backup_to_file = 1
CODE:
RETVAL = sqlite_db_backup_to_file(aTHX_ 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
SV* dbname
SV* tablename
SV* columnname
ALIAS:
}
return TRUE;
}
/* Accesses the SQLite Online Backup API, and fills the currently loaded
* database from the passed filename.
* Usual usage of this would be when you're operating on the :memory:
* special database connection and want to copy it in from a real db.
*/
int
sqlite_db_backup_from_file(pTHX_ SV *dbh, char *filename)
{
D_imp_dbh(dbh);
#if SQLITE_VERSION_NUMBER >= 3006011
int rc;
sqlite3 *pFrom;
sqlite3_backup *pBackup;
if (!DBIc_ACTIVE(imp_dbh)) {
sqlite_error(dbh, -2, "attempt to backup from file on inactive database handle");
return FALSE;
}
croak_if_db_is_null();
rc = sqlite_open(filename, &pFrom);
if ( rc != SQLITE_OK ) {
return FALSE;
}
/* COMPAT: sqlite3_backup_* are only available for 3006011 or newer */
pBackup = sqlite3_backup_init(imp_dbh->db, "main", pFrom, "main");
if (pBackup) {
(void)sqlite3_backup_step(pBackup, -1);
(void)sqlite3_backup_finish(pBackup);
}
rc = sqlite3_errcode(imp_dbh->db);
(void)sqlite3_close(pFrom);
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
}
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:
* special database connection, and want to back it up to an on-disk file.
*/
int
sqlite_db_backup_to_file(pTHX_ SV *dbh, char *filename)
{
D_imp_dbh(dbh);
#if SQLITE_VERSION_NUMBER >= 3006011
int rc;
sqlite3 *pTo;
sqlite3_backup *pBackup;
if (!DBIc_ACTIVE(imp_dbh)) {
sqlite_error(dbh, -2, "attempt to backup to file on inactive database handle");
return FALSE;
}
croak_if_db_is_null();
rc = sqlite_open(filename, &pTo);
if ( rc != SQLITE_OK ) {
return FALSE;
}
/* COMPAT: sqlite3_backup_* are only available for 3006011 or newer */
pBackup = sqlite3_backup_init(pTo, "main", imp_dbh->db, "main");
if (pBackup) {
(void)sqlite3_backup_step(pBackup, -1);
(void)sqlite3_backup_finish(pBackup);
}
rc = sqlite3_errcode(pTo);
(void)sqlite3_close(pTo);
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_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)
{
D_imp_dbh(dbh);
return sqlite3_limit(imp_dbh->db, id, new_value);
}
#ifndef SQLITE_OMIT_LOAD_EXTENSION
int sqlite_db_enable_load_extension(pTHX_ SV *dbh, int onoff);
int sqlite_db_load_extension(pTHX_ SV *dbh, const char *file, const char *proc);
#endif
int sqlite_db_create_aggregate(pTHX_ SV *dbh, const char *name, int argc, SV *aggr, int flags );
int sqlite_db_create_collation(pTHX_ SV *dbh, const char *name, SV *func);
int sqlite_db_progress_handler(pTHX_ SV *dbh, int n_opcodes, SV *handler);
int sqlite_bind_col( SV *sth, imp_sth_t *imp_sth, SV *col, SV *ref, IV sql_type, SV *attribs );
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 );
SV* sqlite_db_update_hook( pTHX_ SV *dbh, SV *hook );
int sqlite_db_set_authorizer( pTHX_ SV *dbh, SV *authorizer );
AV* sqlite_compile_options();
int sqlite_db_trace(pTHX_ SV *dbh, SV *func);
int sqlite_db_profile(pTHX_ SV *dbh, SV *func);
HV* sqlite_db_table_column_metadata(pTHX_ SV *dbh, SV *dbname, SV *tablename, SV *columnname);
HV* _sqlite_db_status(pTHX_ SV *dbh, int reset);
lib/DBD/SQLite.pm view on Meta::CPAN
DBD::SQLite::db->install_method('sqlite_busy_timeout');
DBD::SQLite::db->install_method('sqlite_create_function');
DBD::SQLite::db->install_method('sqlite_create_aggregate');
DBD::SQLite::db->install_method('sqlite_create_collation');
DBD::SQLite::db->install_method('sqlite_collation_needed');
DBD::SQLite::db->install_method('sqlite_progress_handler');
DBD::SQLite::db->install_method('sqlite_commit_hook');
DBD::SQLite::db->install_method('sqlite_rollback_hook');
DBD::SQLite::db->install_method('sqlite_update_hook');
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');
DBD::SQLite::db->install_method('sqlite_trace', { O => 0x0004 });
DBD::SQLite::db->install_method('sqlite_profile', { O => 0x0004 });
DBD::SQLite::db->install_method('sqlite_table_column_metadata', { O => 0x0004 });
DBD::SQLite::db->install_method('sqlite_db_filename', { O => 0x0004 });
DBD::SQLite::db->install_method('sqlite_db_status', { O => 0x0004 });
DBD::SQLite::st->install_method('sqlite_st_status', { O => 0x0004 });
DBD::SQLite::db->install_method('sqlite_create_module');
lib/DBD/SQLite.pm view on Meta::CPAN
is the name of the database (C<main>, C<temp>, etc.) if applicable.
=item $trigger_or_view
is the name of the inner-most trigger or view that is responsible for
the access attempt, or C<undef> if this access attempt is directly from
top-level SQL code.
=back
=head2 $dbh->sqlite_backup_from_file( $filename )
This method accesses the SQLite Online Backup API, and will take a backup of
the named database file, 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.
=head2 $dbh->sqlite_backup_to_file( $filename )
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)
SQLite3 extensions. After the call, you can load extensions like this:
$dbh->sqlite_enable_load_extension(1);
$sth = $dbh->prepare("select load_extension('libmemvfs.so')")
or die "Cannot prepare: " . $dbh->errstr();
** DESTRUCTOR: sqlite3
**
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
** for the [sqlite3] object.
** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
** the [sqlite3] object is successfully destroyed and all associated
** resources are deallocated.
**
** Ideally, applications should [sqlite3_finalize | finalize] all
** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
** with the [sqlite3] object prior to attempting to close the object.
** ^If the database connection is associated with unfinalized prepared
** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
** sqlite3_close() will leave the database connection open and return
** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
** it returns [SQLITE_OK] regardless, but instead of deallocating the database
** connection immediately, it marks the database connection as an unusable
** "zombie" and makes arrangements to automatically deallocate the database
** connection after all prepared statements are finalized, all BLOB handles
** are closed, and all backups have finished. The sqlite3_close_v2() interface
** is intended for use with host languages that are garbage collected, and
** where the order in which destructors are called is arbitrary.
**
** ^If an [sqlite3] object is destroyed while a transaction is open,
** the transaction is automatically rolled back.
**
** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
** must be either a NULL
** pointer or an [sqlite3] object pointer obtained
** from [sqlite3_open()], [sqlite3_open16()], or
void (*xUnpin)(sqlite3_pcache*, void*, int discard);
void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
void (*xDestroy)(sqlite3_pcache*);
};
/*
** CAPI3REF: Online Backup Object
**
** The sqlite3_backup object records state information about an ongoing
** online backup operation. ^The sqlite3_backup object is created by
** a call to [sqlite3_backup_init()] and is destroyed by a call to
** [sqlite3_backup_finish()].
**
** See Also: [Using the SQLite Online Backup API]
*/
typedef struct sqlite3_backup sqlite3_backup;
/*
** CAPI3REF: Online Backup API.
**
** The backup API copies the content of one database into another.
** It is useful either for creating backups of databases or
** for copying in-memory databases to or from persistent files.
**
** See Also: [Using the SQLite Online Backup API]
**
** ^SQLite holds a write transaction open on the destination database file
** for the duration of the backup operation.
** ^The source database is read-locked only while it is being read;
** it is not locked continuously for the entire backup operation.
** ^Thus, the backup may be performed on a live source database without
** preventing other database connections from
** reading or writing to the source database while the backup is underway.
**
** ^(To perform a backup operation:
** <ol>
** <li><b>sqlite3_backup_init()</b> is called once to initialize the
** backup,
** <li><b>sqlite3_backup_step()</b> is called one or more times to transfer
** the data between the two databases, and finally
** <li><b>sqlite3_backup_finish()</b> is called to release all resources
** associated with the backup operation.
** </ol>)^
** There should be exactly one call to sqlite3_backup_finish() for each
** successful call to sqlite3_backup_init().
**
** [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b>
**
** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the
** [database connection] associated with the destination database
** and the database name, respectively.
** ^The database name is "main" for the main database, "temp" for the
** temporary database, or the name specified after the AS keyword in
** an [ATTACH] statement for an attached database.
** ^The S and M arguments passed to
** sqlite3_backup_init(D,N,S,M) identify the [database connection]
** and database name of the source database, respectively.
** ^The source and destination [database connections] (parameters S and D)
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.
**
** ^A call to sqlite3_backup_init() will fail, returning NULL, if
** there is already a read or read-write transaction open on the
** destination database.
**
** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
** returned and an error code and error message are stored in the
** destination [database connection] D.
** ^The error code and message for the failed call to sqlite3_backup_init()
** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
** [sqlite3_errmsg16()] functions.
** ^A successful call to sqlite3_backup_init() returns a pointer to an
** [sqlite3_backup] object.
** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and
** sqlite3_backup_finish() functions to perform the specified backup
** operation.
**
** [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b>
**
** ^Function sqlite3_backup_step(B,N) will copy up to N pages between
** the source and destination databases specified by [sqlite3_backup] object B.
** ^If N is negative, all remaining source pages are copied.
** ^If sqlite3_backup_step(B,N) successfully copies N pages and there
** are still more pages to be copied, then the function returns [SQLITE_OK].
** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages
** from source to destination, then it returns [SQLITE_DONE].
** ^If an error occurs while running sqlite3_backup_step(B,N),
** then an [error code] is returned. ^As well as [SQLITE_OK] and
** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
**
** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if
** <ol>
** <li> the destination database was opened read-only, or
** <li> the destination database is using write-ahead-log journaling
** and the destination and source page sizes differ, or
** <li> the destination database is an in-memory database and the
** destination and source page sizes differ.
** </ol>)^
**
** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
** the [sqlite3_busy_handler | busy-handler function]
** is invoked (if one is specified). ^If the
** busy-handler returns non-zero before the lock is available, then
** [SQLITE_BUSY] is returned to the caller. ^In this case the call to
** sqlite3_backup_step() can be retried later. ^If the source
** [database connection]
** is being used to write to the source database when sqlite3_backup_step()
** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this
** case the call to sqlite3_backup_step() can be retried later on. ^(If
** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
** [SQLITE_READONLY] is returned, then
** there is no point in retrying the call to sqlite3_backup_step(). These
** errors are considered fatal.)^ The application must accept
** that the backup operation has failed and pass the backup operation handle
** to the sqlite3_backup_finish() to release associated resources.
**
** ^The first call to sqlite3_backup_step() obtains an exclusive lock
** on the destination file. ^The exclusive lock is not released until either
** sqlite3_backup_finish() is called or the backup operation is complete
** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to
** sqlite3_backup_step() obtains a [shared lock] on the source database that
** lasts for the duration of the sqlite3_backup_step() call.
** ^Because the source database is not locked between calls to
** sqlite3_backup_step(), the source database may be modified mid-way
** through the backup process. ^If the source database is modified by an
** external process or via a database connection other than the one being
** used by the backup operation, then the backup will be automatically
** restarted by the next call to sqlite3_backup_step(). ^If the source
** database is modified by the using the same database connection as is used
** by the backup operation, then the backup database is automatically
** updated at the same time.
**
** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b>
**
** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the
** application wishes to abandon the backup operation, the application
** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish().
** ^The sqlite3_backup_finish() interfaces releases all
** resources associated with the [sqlite3_backup] object.
** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any
** active write-transaction on the destination database is rolled back.
** The [sqlite3_backup] object is invalid
** and may not be used following a call to sqlite3_backup_finish().
**
** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no
** sqlite3_backup_step() errors occurred, regardless or whether or not
** sqlite3_backup_step() completed.
** ^If an out-of-memory condition or IO error occurred during any prior
** sqlite3_backup_step() call on the same [sqlite3_backup] object, then
** sqlite3_backup_finish() returns the corresponding [error code].
**
** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step()
** is not a permanent error and does not affect the return value of
** sqlite3_backup_finish().
**
** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]]
** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
**
** ^The sqlite3_backup_remaining() routine returns the number of pages still
** to be backed up at the conclusion of the most recent sqlite3_backup_step().
** ^The sqlite3_backup_pagecount() routine returns the total number of pages
** in the source database at the conclusion of the most recent
** sqlite3_backup_step().
** ^(The values returned by these functions are only updated by
** sqlite3_backup_step(). If the source database is modified in a way that
** changes the size of the source database or the number of pages remaining,
** those changes are not reflected in the output of sqlite3_backup_pagecount()
** and sqlite3_backup_remaining() until after the next
** sqlite3_backup_step().)^
**
** <b>Concurrent Usage of Database Handles</b>
**
** ^The source [database connection] may be used by the application for other
** purposes while a backup operation is underway or being initialized.
** ^If SQLite is compiled and configured to support threadsafe database
** connections, then the source database connection may be used concurrently
** from within other threads.
**
** However, the application must guarantee that the destination
** [database connection] is not passed to any other API (by any thread) after
** sqlite3_backup_init() is called and before the corresponding call to
** sqlite3_backup_finish(). SQLite does not currently check to see
** if the application incorrectly accesses the destination [database connection]
** and so no error code is reported, but the operations may malfunction
** nevertheless. Use of the destination database connection while a
** backup is in progress might also cause a mutex deadlock.
**
** If running in [shared cache mode], the application must
** guarantee that the shared cache used by the destination database
** is not accessed while the backup is running. In practice this means
** that the application must guarantee that the disk file being
** backed up to is not accessed by any connection within the process,
** not just the specific connection that was passed to sqlite3_backup_init().
**
** The [sqlite3_backup] object itself is partially threadsafe. Multiple
** threads may safely make multiple concurrent calls to sqlite3_backup_step().
** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
** APIs are not strictly speaking threadsafe. If they are invoked at the
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
*/
SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3 *pDest, /* Destination database handle */
const char *zDestName, /* Destination database name */
sqlite3 *pSource, /* Source database handle */
const char *zSourceName /* Source database name */
);
SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
/*
** CAPI3REF: Unlock Notification
** METHOD: sqlite3
**
** ^When running in shared-cache mode, a database operation may fail with
** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
** individual tables within the shared-cache cannot be obtained. See
** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
** ^This API may be used to register a callback that SQLite will invoke
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
** invoke sqlite3_free() on the serialization buffer when the database
** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
** SQLite will try to increase the buffer size using sqlite3_realloc64()
** if writes on the database cause it to grow larger than M bytes.
**
** Applications must not modify the buffer P or invalidate it before
** the database connection D is closed.
**
** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
** database is currently in a read transaction or is involved in a backup
** operation.
**
** It is not possible to deserialized into the TEMP database. If the
** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the
** function returns SQLITE_ERROR.
**
** The deserialized database should not be in [WAL mode]. If the database
** is in WAL mode, then any attempt to use the database file will result
** in an [SQLITE_CANTOPEN] error. The application can set the
** [file format version numbers] (bytes 18 and 19) of the input database P
SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int);
SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager*, int);
SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64);
SQLITE_PRIVATE void sqlite3PagerShrink(Pager*);
SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned);
SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int);
SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*);
SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*);
SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*);
SQLITE_PRIVATE int sqlite3PagerFlush(Pager*);
/* Functions used to obtain and release page references. */
SQLITE_PRIVATE int sqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag);
SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno);
SQLITE_PRIVATE void sqlite3PagerRef(DbPage*);
SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*);
SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*);
SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage*);
SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, i64);
SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8);
SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*);
SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3*,const Expr*);
SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *);
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
#ifndef SQLITE_OMIT_SUBQUERY
SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse*, Expr*);
#else
# define sqlite3ExprCheckIN(x,y) SQLITE_OK
#endif
#ifdef SQLITE_ENABLE_STAT4
SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(
Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*);
rc = robust_ftruncate(pFile->h, nByte);
if( rc ){
storeLastErrno(pFile, errno);
return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
}else{
#ifdef SQLITE_DEBUG
/* If we are doing a normal write to a database file (as opposed to
** doing a hot-journal rollback or a write to some file other than a
** normal database file) and we truncate the file to zero length,
** that effectively updates the change counter. This might happen
** when restoring a database using the backup API from a zero-length
** source.
*/
if( pFile->inNormalWrite && nByte==0 ){
pFile->transCntrChng = 1;
}
#endif
#if SQLITE_MAX_MMAP_SIZE>0
/* If the file was just truncated to a size smaller than the currently
** mapped region, reduce the effective mapping size as well. SQLite will
int errCode; /* One of several kinds of errors */
int nRec; /* Pages journalled since last j-header written */
u32 cksumInit; /* Quasi-random value added to every checksum */
u32 nSubRec; /* Number of records written to sub-journal */
Bitvec *pInJournal; /* One bit for each page in the database file */
sqlite3_file *fd; /* File descriptor for database */
sqlite3_file *jfd; /* File descriptor for main journal */
sqlite3_file *sjfd; /* File descriptor for sub-journal */
i64 journalOff; /* Current write offset in the journal file */
i64 journalHdr; /* Byte offset to previous journal header */
sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */
PagerSavepoint *aSavepoint; /* Array of active savepoints */
int nSavepoint; /* Number of elements in aSavepoint[] */
u32 iDataVersion; /* Changes whenever database content changes */
char dbFileVers[16]; /* Changes whenever database file changes */
int nMmapOut; /* Number of mmap pages currently outstanding */
sqlite3_int64 szMmap; /* Desired maximum mmap size */
PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */
/*
** End of the routinely-changing class members
sqlite3PcacheDrop(pPg);
}else{
rc = readDbPage(pPg);
if( rc==SQLITE_OK ){
pPager->xReiniter(pPg);
}
sqlite3PagerUnrefNotNull(pPg);
}
}
/* Normally, if a transaction is rolled back, any backup processes are
** updated as data is copied out of the rollback journal and into the
** database. This is not generally possible with a WAL database, as
** rollback involves simply truncating the log file. Therefore, if one
** or more frames have already been written to the log (and therefore
** also copied into the backup databases) as part of this transaction,
** the backups must be restarted.
*/
sqlite3BackupRestart(pPager->pBackup);
return rc;
}
/*
** This function is called to rollback a transaction on a WAL database.
*/
static int pagerRollbackWal(Pager *pPager){
rc = pagerUndoCallback((void *)pPager, pList->pgno);
pList = pNext;
}
return rc;
}
/*
** This function is a wrapper around sqlite3WalFrames(). As well as logging
** the contents of the list of pages headed by pList (connected by pDirty),
** this function notifies any active backup processes that the pages have
** changed.
**
** The list of pages passed into this routine is always sorted by page number.
** Hence, if page 1 appears anywhere on the list, it will be the first page.
*/
static int pagerWalFrames(
Pager *pPager, /* Pager object */
PgHdr *pList, /* List of frames to log */
Pgno nTruncate, /* Database size after this commit */
int isCommit /* True if this is a commit */
** page caused the database file to grow, update dbFileSize.
*/
if( pgno==1 ){
memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
}
if( pgno>pPager->dbFileSize ){
pPager->dbFileSize = pgno;
}
pPager->aStat[PAGER_STAT_WRITE]++;
/* Update any backup objects copying the contents of this pager. */
sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData);
PAGERTRACE(("STORE %d page %d hash(%08x)\n",
PAGERID(pPager), pgno, pager_pagehash(pList)));
IOTRACE(("PGOUT %p %d\n", pPager, pgno));
PAGER_INCR(sqlite3_pager_writedb_count);
}else{
PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno));
}
pager_set_pagehash(pList);
pPager->zFilename, zSuper, pPager->dbSize));
/* If no database changes have been made, return early. */
if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
assert( MEMDB==0 || pPager->tempFile );
assert( isOpen(pPager->fd) || pPager->tempFile );
if( 0==pagerFlushOnCommit(pPager, 1) ){
/* If this is an in-memory db, or no pages have been written to, or this
** function has already been called, it is mostly a no-op. However, any
** backup in progress needs to be restarted. */
sqlite3BackupRestart(pPager->pBackup);
}else{
PgHdr *pList;
if( pagerUseWal(pPager) ){
PgHdr *pPageOne = 0;
pList = sqlite3PcacheDirtyList(pPager->pPCache);
if( pList==0 ){
/* Must have at least one page for the WAL commit flag.
** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0);
*/
SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
if( iLimit>=-1 ){
pPager->journalSizeLimit = iLimit;
sqlite3WalLimit(pPager->pWal, iLimit);
}
return pPager->journalSizeLimit;
}
/*
** Return a pointer to the pPager->pBackup variable. The backup module
** in backup.c maintains the content of this variable. This module
** uses it opaquely as an argument to sqlite3BackupRestart() and
** sqlite3BackupUpdate() only.
*/
SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
return &pPager->pBackup;
}
#ifndef SQLITE_OMIT_VACUUM
/*
** Unless this is an in-memory or temporary database, clear the pager cache.
*/
SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
assert( MEMDB==0 || pPager->tempFile );
if( pPager->tempFile==0 ) pager_reset(pPager);
** they often do so without holding sqlite3.mutex.
*/
struct Btree {
sqlite3 *db; /* The database connection holding this btree */
BtShared *pBt; /* Sharable content of this btree */
u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */
u8 sharable; /* True if we can share pBt with another db */
u8 locked; /* True if db currently has pBt locked */
u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */
int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */
int nBackup; /* Number of backup operations reading this btree */
u32 iBDataVersion; /* Combines with pBt->pPager->iDataVersion */
Btree *pNext; /* List of other sharable Btrees from the same db */
Btree *pPrev; /* Back pointer of the same list */
#ifdef SQLITE_DEBUG
u64 nSeek; /* Calls to sqlite3BtreeMovetoUnpacked() */
#endif
#ifndef SQLITE_OMIT_SHARED_CACHE
BtLock lock; /* Object used to lock page 1 */
#endif
};
*/
SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
return p->pBt->pageSize;
}
/*
** This function is similar to sqlite3BtreeGetReserve(), except that it
** may only be called if it is guaranteed that the b-tree mutex is already
** held.
**
** This is useful in one special case in the backup API code where it is
** known that the shared b-tree mutex is held, but the mutex on the
** database handle that owns *p is not. In this case if sqlite3BtreeEnter()
** were to be called, it might collide with some other operation on the
** database handle that owns *p, causing undefined behavior.
*/
SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){
int n;
assert( sqlite3_mutex_held(p->pBt->mutex) );
n = p->pBt->pageSize - p->pBt->usableSize;
return n;
}else{
rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt);
}
sqlite3BtreeLeave(p);
}
return rc;
}
#endif
/*
** Return true if there is currently a backup running on Btree p.
*/
SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){
assert( p );
assert( sqlite3_mutex_held(p->db->mutex) );
return p->nBackup!=0;
}
/*
** This function returns a pointer to a blob of memory associated with
** a single shared-btree. The memory is used by client code for its own
** the Btree handle passed as the only argument. For private caches
** this is always 1. For shared caches it may be 1 or greater.
*/
SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){
testcase( p->sharable );
return p->pBt->nRef;
}
#endif
/************** End of btree.c ***********************************************/
/************** Begin file backup.c ******************************************/
/*
** 2009 January 28
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains the implementation of the sqlite3_backup_XXX()
** API functions and the related features.
*/
/* #include "sqliteInt.h" */
/* #include "btreeInt.h" */
/*
** Structure allocated for each backup operation.
*/
struct sqlite3_backup {
sqlite3* pDestDb; /* Destination database handle */
Btree *pDest; /* Destination b-tree file */
u32 iDestSchema; /* Original schema cookie in destination */
int bDestLocked; /* True once a write-transaction is open on pDest */
Pgno iNext; /* Page number of the next source page to copy */
sqlite3* pSrcDb; /* Source database handle */
Btree *pSrc; /* Source b-tree file */
int rc; /* Backup process error code */
/* These two variables are set by every call to backup_step(). They are
** read by calls to backup_remaining() and backup_pagecount().
*/
Pgno nRemaining; /* Number of pages left to copy */
Pgno nPagecount; /* Total number of pages to copy */
int isAttached; /* True once backup has been registered with pager */
sqlite3_backup *pNext; /* Next backup associated with source pager */
};
/*
** THREAD SAFETY NOTES:
**
** Once it has been created using backup_init(), a single sqlite3_backup
** structure may be accessed via two groups of thread-safe entry points:
**
** * Via the sqlite3_backup_XXX() API function backup_step() and
** backup_finish(). Both these functions obtain the source database
** handle mutex and the mutex associated with the source BtShared
** structure, in that order.
**
** * Via the BackupUpdate() and BackupRestart() functions, which are
** invoked by the pager layer to report various state changes in
** the page cache associated with the source database. The mutex
** associated with the source database BtShared structure will always
** be held when either of these functions are invoked.
**
** The other sqlite3_backup_XXX() API functions, backup_remaining() and
** backup_pagecount() are not thread-safe functions. If they are called
** while some other thread is calling backup_step() or backup_finish(),
** the values returned may be invalid. There is no way for a call to
** BackupUpdate() or BackupRestart() to interfere with backup_remaining()
** or backup_pagecount().
**
** Depending on the SQLite configuration, the database handles and/or
** the Btree objects may have their own mutexes that require locking.
** Non-sharable Btrees (in-memory databases for example), do not have
** associated mutexes.
*/
/*
** Return a pointer corresponding to database zDb (i.e. "main", "temp")
** in connection handle pDb. If such a database cannot be found, return
return 0;
}
return pDb->aDb[i].pBt;
}
/*
** Attempt to set the page size of the destination to match the page size
** of the source.
*/
static int setDestPgsz(sqlite3_backup *p){
int rc;
rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),0,0);
return rc;
}
/*
** Check that there is no open read-transaction on the b-tree passed as the
** second argument. If there is not, return SQLITE_OK. Otherwise, if there
** is an open read-transaction, return SQLITE_ERROR and leave an error
** message in database handle db.
*/
static int checkReadTransaction(sqlite3 *db, Btree *p){
if( sqlite3BtreeTxnState(p)!=SQLITE_TXN_NONE ){
sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use");
return SQLITE_ERROR;
}
return SQLITE_OK;
}
/*
** Create an sqlite3_backup process to copy the contents of zSrcDb from
** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
** a pointer to the new sqlite3_backup object.
**
** If an error occurs, NULL is returned and an error code and error message
** stored in database handle pDestDb.
*/
SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3* pDestDb, /* Database to write to */
const char *zDestDb, /* Name of database within pDestDb */
sqlite3* pSrcDb, /* Database connection to read from */
const char *zSrcDb /* Name of database within pSrcDb */
){
sqlite3_backup *p; /* Value to return */
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
/* Lock the source database handle. The destination database
** handle is not locked in this routine, but it is locked in
** sqlite3_backup_step(). The user is required to ensure that no
** other thread accesses the destination handle for the duration
** of the backup operation. Any attempt to use the destination
** database connection while a backup is in progress may cause
** a malfunction or a deadlock.
*/
sqlite3_mutex_enter(pSrcDb->mutex);
sqlite3_mutex_enter(pDestDb->mutex);
if( pSrcDb==pDestDb ){
sqlite3ErrorWithMsg(
pDestDb, SQLITE_ERROR, "source and destination must be distinct"
);
p = 0;
}else {
/* Allocate space for a new sqlite3_backup object...
** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
** call to sqlite3_backup_init() and is destroyed by a call to
** sqlite3_backup_finish(). */
p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
if( !p ){
sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT);
}
}
/* If the allocation succeeded, populate the new object. */
if( p ){
p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb);
p->pDest = findBtree(pDestDb, pDestDb, zDestDb);
p->pDestDb = pDestDb;
p->pSrcDb = pSrcDb;
p->iNext = 1;
p->isAttached = 0;
if( 0==p->pSrc || 0==p->pDest
|| checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK
){
/* One (or both) of the named databases did not exist or an OOM
** error was hit. Or there is a transaction open on the destination
** database. The error has already been written into the pDestDb
** handle. All that is left to do here is free the sqlite3_backup
** structure. */
sqlite3_free(p);
p = 0;
}
}
if( p ){
p->pSrc->nBackup++;
}
sqlite3_mutex_leave(pDestDb->mutex);
sqlite3_mutex_leave(pSrcDb->mutex);
return p;
}
/*
** Argument rc is an SQLite error code. Return true if this error is
** considered fatal if encountered during a backup operation. All errors
** are considered fatal except for SQLITE_BUSY and SQLITE_LOCKED.
*/
static int isFatalError(int rc){
return (rc!=SQLITE_OK && rc!=SQLITE_BUSY && ALWAYS(rc!=SQLITE_LOCKED));
}
/*
** Parameter zSrcData points to a buffer containing the data for
** page iSrcPg from the source database. Copy this data into the
** destination database.
*/
static int backupOnePage(
sqlite3_backup *p, /* Backup handle */
Pgno iSrcPg, /* Source database page to backup */
const u8 *zSrcData, /* Source database page data */
int bUpdate /* True for an update, false otherwise */
){
Pager * const pDestPager = sqlite3BtreePager(p->pDest);
const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc);
int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest);
const int nCopy = MIN(nSrcPgsz, nDestPgsz);
const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz;
int rc = SQLITE_OK;
i64 iOff;
}
/*
** If pFile is currently larger than iSize bytes, then truncate it to
** exactly iSize bytes. If pFile is not larger than iSize bytes, then
** this function is a no-op.
**
** Return SQLITE_OK if everything is successful, or an SQLite error
** code if an error occurs.
*/
static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){
i64 iCurrent;
int rc = sqlite3OsFileSize(pFile, &iCurrent);
if( rc==SQLITE_OK && iCurrent>iSize ){
rc = sqlite3OsTruncate(pFile, iSize);
}
return rc;
}
/*
** Register this backup object with the associated source pager for
** callbacks when pages are changed or the cache invalidated.
*/
static void attachBackupObject(sqlite3_backup *p){
sqlite3_backup **pp;
assert( sqlite3BtreeHoldsMutex(p->pSrc) );
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
p->pNext = *pp;
*pp = p;
p->isAttached = 1;
}
/*
** Copy nPage pages from the source b-tree to the destination.
*/
SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
int rc;
int destMode; /* Destination journal mode */
int pgszSrc = 0; /* Source page size */
int pgszDest = 0; /* Destination page size */
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ) return SQLITE_MISUSE_BKPT;
#endif
sqlite3_mutex_enter(p->pSrcDb->mutex);
sqlite3BtreeEnter(p->pSrc);
/* If there is no open read-transaction on the source database, open
** one now. If a transaction is opened here, then it will be closed
** before this function exits.
*/
if( rc==SQLITE_OK && SQLITE_TXN_NONE==sqlite3BtreeTxnState(p->pSrc) ){
rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0);
bCloseTrans = 1;
}
/* If the destination database has not yet been locked (i.e. if this
** is the first call to backup_step() for the current backup operation),
** try to set its page size to the same as the source database. This
** is especially important on ZipVFS systems, as in that case it is
** not possible to create a database file that uses one page size by
** writing to it with another. */
if( p->bDestLocked==0 && rc==SQLITE_OK && setDestPgsz(p)==SQLITE_NOMEM ){
rc = SQLITE_NOMEM;
}
/* Lock the destination database, if it is not locked already. */
if( SQLITE_OK==rc && p->bDestLocked==0
&& SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2,
(int*)&p->iDestSchema))
){
p->bDestLocked = 1;
}
/* Do not allow backup if the destination database is in WAL mode
** and the page sizes are different between source and destination */
pgszSrc = sqlite3BtreeGetPageSize(p->pSrc);
pgszDest = sqlite3BtreeGetPageSize(p->pDest);
destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest));
if( SQLITE_OK==rc
&& (destMode==PAGER_JOURNALMODE_WAL || sqlite3PagerIsMemdb(pDestPager))
&& pgszSrc!=pgszDest
){
rc = SQLITE_READONLY;
}
** source pager for the number of pages in the database.
*/
nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc);
assert( nSrcPage>=0 );
for(ii=0; (nPage<0 || ii<nPage) && p->iNext<=(Pgno)nSrcPage && !rc; ii++){
const Pgno iSrcPg = p->iNext; /* Source page number */
if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){
DbPage *pSrcPg; /* Source page object */
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY);
if( rc==SQLITE_OK ){
rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0);
sqlite3PagerUnref(pSrcPg);
}
}
p->iNext++;
}
if( rc==SQLITE_OK ){
p->nPagecount = nSrcPage;
p->nRemaining = nSrcPage+1-p->iNext;
if( p->iNext>(Pgno)nSrcPage ){
rc = SQLITE_DONE;
PgHdr *pSrcPg = 0;
const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1);
rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg, 0);
if( rc==SQLITE_OK ){
u8 *zData = sqlite3PagerGetData(pSrcPg);
rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff);
}
sqlite3PagerUnref(pSrcPg);
}
if( rc==SQLITE_OK ){
rc = backupTruncateFile(pFile, iSize);
}
/* Sync the database file to disk. */
if( rc==SQLITE_OK ){
rc = sqlite3PagerSync(pDestPager, 0);
}
}else{
sqlite3PagerTruncateImage(pDestPager, nDestTruncate);
rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0);
}
}
if( p->pDestDb ){
sqlite3_mutex_leave(p->pDestDb->mutex);
}
sqlite3BtreeLeave(p->pSrc);
sqlite3_mutex_leave(p->pSrcDb->mutex);
return rc;
}
/*
** Release all resources associated with an sqlite3_backup* handle.
*/
SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
sqlite3 *pSrcDb; /* Source database connection */
int rc; /* Value to return */
/* Enter the mutexes */
if( p==0 ) return SQLITE_OK;
pSrcDb = p->pSrcDb;
sqlite3_mutex_enter(pSrcDb->mutex);
sqlite3BtreeEnter(p->pSrc);
if( p->pDestDb ){
sqlite3_mutex_enter(p->pDestDb->mutex);
}
/* Detach this backup from the source pager. */
if( p->pDestDb ){
p->pSrc->nBackup--;
}
if( p->isAttached ){
pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc));
assert( pp!=0 );
while( *pp!=p ){
pp = &(*pp)->pNext;
assert( pp!=0 );
}
}
/* If a transaction is still open on the Btree, roll it back. */
sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0);
/* Set the error code of the destination database handle. */
rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
if( p->pDestDb ){
sqlite3Error(p->pDestDb, rc);
/* Exit the mutexes and free the backup context structure. */
sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
}
sqlite3BtreeLeave(p->pSrc);
if( p->pDestDb ){
/* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a
** call to sqlite3_backup_init() and is destroyed by a call to
** sqlite3_backup_finish(). */
sqlite3_free(p);
}
sqlite3LeaveMutexAndCloseZombie(pSrcDb);
return rc;
}
/*
** Return the number of pages still to be backed up as of the most recent
** call to sqlite3_backup_step().
*/
SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return p->nRemaining;
}
/*
** Return the total number of pages in the source database as of the most
** recent call to sqlite3_backup_step().
*/
SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
#ifdef SQLITE_ENABLE_API_ARMOR
if( p==0 ){
(void)SQLITE_MISUSE_BKPT;
return 0;
}
#endif
return p->nPagecount;
}
/*
** This function is called after the contents of page iPage of the
** source database have been modified. If page iPage has already been
** copied into the destination database, then the data written to the
** destination is now invalidated. The destination copy of iPage needs
** to be updated with the new data before the backup operation is
** complete.
**
** It is assumed that the mutex associated with the BtShared object
** corresponding to the source database is held when this function is
** called.
*/
static SQLITE_NOINLINE void backupUpdate(
sqlite3_backup *p,
Pgno iPage,
const u8 *aData
){
assert( p!=0 );
do{
assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
if( !isFatalError(p->rc) && iPage<p->iNext ){
/* The backup process p has already copied page iPage. But now it
** has been modified by a transaction on the source pager. Copy
** the new data into the backup.
*/
int rc;
assert( p->pDestDb );
sqlite3_mutex_enter(p->pDestDb->mutex);
rc = backupOnePage(p, iPage, aData, 1);
sqlite3_mutex_leave(p->pDestDb->mutex);
assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED );
if( rc!=SQLITE_OK ){
p->rc = rc;
}
}
}while( (p = p->pNext)!=0 );
}
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){
if( pBackup ) backupUpdate(pBackup, iPage, aData);
}
/*
** Restart the backup process. This is called when the pager layer
** detects that the database has been modified by an external database
** connection. In this case there is no way of knowing which of the
** pages that have been copied into the destination database are still
** valid and which are not, so the entire process needs to be restarted.
**
** It is assumed that the mutex associated with the BtShared object
** corresponding to the source database is held when this function is
** called.
*/
SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){
sqlite3_backup *p; /* Iterator variable */
for(p=pBackup; p; p=p->pNext){
assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) );
p->iNext = 1;
}
}
#ifndef SQLITE_OMIT_VACUUM
/*
** Copy the complete content of pBtFrom into pBtTo. A transaction
** must be active for both files.
**
** The size of file pTo may be reduced by this operation. If anything
** goes wrong, the transaction on pTo is rolled back. If successful, the
** transaction is committed before returning.
*/
SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
int rc;
sqlite3_file *pFd; /* File descriptor for database pTo */
sqlite3_backup b;
sqlite3BtreeEnter(pTo);
sqlite3BtreeEnter(pFrom);
assert( sqlite3BtreeTxnState(pTo)==SQLITE_TXN_WRITE );
pFd = sqlite3PagerFile(sqlite3BtreePager(pTo));
if( pFd->pMethods ){
i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom);
rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte);
if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
if( rc ) goto copy_finished;
}
/* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
** to 0. This is used by the implementations of sqlite3_backup_step()
** and sqlite3_backup_finish() to detect that they are being called
** from this function, not directly by the user.
*/
memset(&b, 0, sizeof(b));
b.pSrcDb = pFrom->db;
b.pSrc = pFrom;
b.pDest = pTo;
b.iNext = 1;
/* 0x7FFFFFFF is the hard limit for the number of pages in a database
** file. By passing this as the number of pages to copy to
** sqlite3_backup_step(), we can guarantee that the copy finishes
** within a single call (unless an error occurs). The assert() statement
** checks this assumption - (p->rc) should be set to either SQLITE_DONE
** or an error code. */
sqlite3_backup_step(&b, 0x7FFFFFFF);
assert( b.rc!=SQLITE_OK );
rc = sqlite3_backup_finish(&b);
if( rc==SQLITE_OK ){
pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED;
}else{
sqlite3PagerClearCache(sqlite3BtreePager(b.pDest));
}
assert( sqlite3BtreeTxnState(pTo)!=SQLITE_TXN_WRITE );
copy_finished:
sqlite3BtreeLeave(pFrom);
sqlite3BtreeLeave(pTo);
return rc;
}
#endif /* SQLITE_OMIT_VACUUM */
/************** End of backup.c **********************************************/
/************** Begin file vdbemem.c *****************************************/
/*
** 2004 May 26
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
** If P5 is positive and the jump is taken, then event counter
** number P5-1 in the prepared statement is incremented.
**
** See also: Prev
*/
/* Opcode: Prev P1 P2 P3 * P5
**
** Back up cursor P1 so that it points to the previous key/data pair in its
** table or index. If there is no previous key/value pairs then fall through
** to the following instruction. But if the cursor backup was successful,
** jump immediately to P2.
**
**
** The Prev opcode is only valid following an SeekLT, SeekLE, or
** OP_Last opcode used to position the cursor. Prev is not allowed
** to follow SeekGT, SeekGE, or OP_Rewind.
**
** The P1 cursor must be for a real table, not a pseudo-table. If P1 is
** not open then the behavior is undefined.
**
static void likeFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const unsigned char *zA, *zB;
u32 escape;
int nPat;
sqlite3 *db = sqlite3_context_db_handle(context);
struct compareInfo *pInfo = sqlite3_user_data(context);
struct compareInfo backupInfo;
#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
if( sqlite3_value_type(argv[0])==SQLITE_BLOB
|| sqlite3_value_type(argv[1])==SQLITE_BLOB
){
#ifdef SQLITE_TEST
sqlite3_like_count++;
#endif
sqlite3_result_int(context, 0);
return;
*/
const unsigned char *zEsc = sqlite3_value_text(argv[2]);
if( zEsc==0 ) return;
if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){
sqlite3_result_error(context,
"ESCAPE expression must be a single character", -1);
return;
}
escape = sqlite3Utf8Read(&zEsc);
if( escape==pInfo->matchAll || escape==pInfo->matchOne ){
memcpy(&backupInfo, pInfo, sizeof(backupInfo));
pInfo = &backupInfo;
if( escape==pInfo->matchAll ) pInfo->matchAll = 0;
if( escape==pInfo->matchOne ) pInfo->matchOne = 0;
}
}else{
escape = pInfo->matchSet;
}
zB = sqlite3_value_text(argv[0]);
zA = sqlite3_value_text(argv[1]);
if( zA && zB ){
#ifdef SQLITE_TEST
void (*result_zeroblob)(sqlite3_context*,int);
void (*result_error_code)(sqlite3_context*,int);
int (*test_control)(int, ...);
void (*randomness)(int,void*);
sqlite3 *(*context_db_handle)(sqlite3_context*);
int (*extended_result_codes)(sqlite3*,int);
int (*limit)(sqlite3*,int,int);
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
const char *(*sql)(sqlite3_stmt*);
int (*status)(int,int*,int*,int);
int (*backup_finish)(sqlite3_backup*);
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
int (*backup_pagecount)(sqlite3_backup*);
int (*backup_remaining)(sqlite3_backup*);
int (*backup_step)(sqlite3_backup*,int);
const char *(*compileoption_get)(int);
int (*compileoption_used)(const char*);
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*));
int (*db_config)(sqlite3*,int,...);
sqlite3_mutex *(*db_mutex)(sqlite3*);
int (*db_status)(sqlite3*,int,int*,int*,int);
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
#define sqlite3_result_error_code sqlite3_api->result_error_code
#define sqlite3_test_control sqlite3_api->test_control
#define sqlite3_randomness sqlite3_api->randomness
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
#define sqlite3_limit sqlite3_api->limit
#define sqlite3_next_stmt sqlite3_api->next_stmt
#define sqlite3_sql sqlite3_api->sql
#define sqlite3_status sqlite3_api->status
#define sqlite3_backup_finish sqlite3_api->backup_finish
#define sqlite3_backup_init sqlite3_api->backup_init
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
#define sqlite3_backup_step sqlite3_api->backup_step
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
#define sqlite3_db_config sqlite3_api->db_config
#define sqlite3_db_mutex sqlite3_api->db_mutex
#define sqlite3_db_status sqlite3_api->db_status
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
#define sqlite3_log sqlite3_api->log
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
#define sqlite3_sourceid sqlite3_api->sourceid
*/
sqlite3_extended_result_codes,
sqlite3_limit,
sqlite3_next_stmt,
sqlite3_sql,
sqlite3_status,
/*
** Added for 3.7.4
*/
sqlite3_backup_finish,
sqlite3_backup_init,
sqlite3_backup_pagecount,
sqlite3_backup_remaining,
sqlite3_backup_step,
#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
sqlite3_compileoption_get,
sqlite3_compileoption_used,
#else
0,
0,
#endif
sqlite3_create_function_v2,
sqlite3_db_config,
sqlite3_db_mutex,
}
sqlite3VtabUnlockList(db);
sqlite3BtreeLeaveAll(db);
#else
UNUSED_PARAMETER(db);
#endif
}
/*
** Return TRUE if database connection db has unfinalized prepared
** statements or unfinished sqlite3_backup objects.
*/
static int connectionIsBusy(sqlite3 *db){
int j;
assert( sqlite3_mutex_held(db->mutex) );
if( db->pVdbe ) return 1;
for(j=0; j<db->nDb; j++){
Btree *pBt = db->aDb[j].pBt;
if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1;
}
return 0;
** SQL statements below, as the v-table implementation may be storing
** some prepared statements internally.
*/
sqlite3VtabRollback(db);
/* Legacy behavior (sqlite3_close() behavior) is to return
** SQLITE_BUSY if the connection can not be closed immediately.
*/
if( !forceZombie && connectionIsBusy(db) ){
sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized "
"statements or unfinished backups");
sqlite3_mutex_leave(db->mutex);
return SQLITE_BUSY;
}
#ifdef SQLITE_ENABLE_SQLLOG
if( sqlite3GlobalConfig.xSqllog ){
/* Closing the handle. Fourth parameter is passed the value 2. */
sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2);
}
#endif
if( x>iTxn ) iTxn = x;
}
sqlite3_mutex_leave(db->mutex);
return iTxn;
}
/*
** Two variations on the public interface for closing a database
** connection. The sqlite3_close() version returns SQLITE_BUSY and
** leaves the connection open if there are unfinalized prepared
** statements or unfinished sqlite3_backups. The sqlite3_close_v2()
** version forces the connection to become a zombie if there are
** unclosed resources, and arranges for deallocation when the last
** prepare statement or sqlite3_backup closes.
*/
SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
/*
** Close the mutex on database connection db.
**
** Furthermore, if database connection db is a zombie (meaning that there
** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and
** every sqlite3_stmt has now been finalized and every sqlite3_backup has
** finished, then free all resources.
*/
SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
HashElem *i; /* Hash table iterator */
int j;
/* If there are outstanding sqlite3_stmt or sqlite3_backup objects
** or if the connection has not yet been closed by sqlite3_close_v2(),
** then just leave the mutex and return.
*/
if( db->eOpenState!=SQLITE_STATE_ZOMBIE || connectionIsBusy(db) ){
sqlite3_mutex_leave(db->mutex);
return;
}
/* If we reach this point, it means that the database connection has
** closed all sqlite3_stmt and sqlite3_backup objects and has been
** passed to sqlite3_close (meaning that it is a zombie). Therefore,
** go ahead and free all resources.
*/
/* If a transaction is open, roll it back. This also ensures that if
** any database schemas have been modified by an uncommitted transaction
** they are reset. And that the required b-tree mutex is held to make
** the pager rollback and schema reset an atomic operation. */
sqlite3RollbackAll(db, SQLITE_OK);
** DESTRUCTOR: sqlite3
**
** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
** for the [sqlite3] object.
** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if
** the [sqlite3] object is successfully destroyed and all associated
** resources are deallocated.
**
** Ideally, applications should [sqlite3_finalize | finalize] all
** [prepared statements], [sqlite3_blob_close | close] all [BLOB handles], and
** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated
** with the [sqlite3] object prior to attempting to close the object.
** ^If the database connection is associated with unfinalized prepared
** statements, BLOB handlers, and/or unfinished sqlite3_backup objects then
** sqlite3_close() will leave the database connection open and return
** [SQLITE_BUSY]. ^If sqlite3_close_v2() is called with unfinalized prepared
** statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups,
** it returns [SQLITE_OK] regardless, but instead of deallocating the database
** connection immediately, it marks the database connection as an unusable
** "zombie" and makes arrangements to automatically deallocate the database
** connection after all prepared statements are finalized, all BLOB handles
** are closed, and all backups have finished. The sqlite3_close_v2() interface
** is intended for use with host languages that are garbage collected, and
** where the order in which destructors are called is arbitrary.
**
** ^If an [sqlite3] object is destroyed while a transaction is open,
** the transaction is automatically rolled back.
**
** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)]
** must be either a NULL
** pointer or an [sqlite3] object pointer obtained
** from [sqlite3_open()], [sqlite3_open16()], or
void (*xUnpin)(sqlite3_pcache*, void*, int discard);
void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey);
void (*xTruncate)(sqlite3_pcache*, unsigned iLimit);
void (*xDestroy)(sqlite3_pcache*);
};
/*
** CAPI3REF: Online Backup Object
**
** The sqlite3_backup object records state information about an ongoing
** online backup operation. ^The sqlite3_backup object is created by
** a call to [sqlite3_backup_init()] and is destroyed by a call to
** [sqlite3_backup_finish()].
**
** See Also: [Using the SQLite Online Backup API]
*/
typedef struct sqlite3_backup sqlite3_backup;
/*
** CAPI3REF: Online Backup API.
**
** The backup API copies the content of one database into another.
** It is useful either for creating backups of databases or
** for copying in-memory databases to or from persistent files.
**
** See Also: [Using the SQLite Online Backup API]
**
** ^SQLite holds a write transaction open on the destination database file
** for the duration of the backup operation.
** ^The source database is read-locked only while it is being read;
** it is not locked continuously for the entire backup operation.
** ^Thus, the backup may be performed on a live source database without
** preventing other database connections from
** reading or writing to the source database while the backup is underway.
**
** ^(To perform a backup operation:
** <ol>
** <li><b>sqlite3_backup_init()</b> is called once to initialize the
** backup,
** <li><b>sqlite3_backup_step()</b> is called one or more times to transfer
** the data between the two databases, and finally
** <li><b>sqlite3_backup_finish()</b> is called to release all resources
** associated with the backup operation.
** </ol>)^
** There should be exactly one call to sqlite3_backup_finish() for each
** successful call to sqlite3_backup_init().
**
** [[sqlite3_backup_init()]] <b>sqlite3_backup_init()</b>
**
** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the
** [database connection] associated with the destination database
** and the database name, respectively.
** ^The database name is "main" for the main database, "temp" for the
** temporary database, or the name specified after the AS keyword in
** an [ATTACH] statement for an attached database.
** ^The S and M arguments passed to
** sqlite3_backup_init(D,N,S,M) identify the [database connection]
** and database name of the source database, respectively.
** ^The source and destination [database connections] (parameters S and D)
** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
** an error.
**
** ^A call to sqlite3_backup_init() will fail, returning NULL, if
** there is already a read or read-write transaction open on the
** destination database.
**
** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
** returned and an error code and error message are stored in the
** destination [database connection] D.
** ^The error code and message for the failed call to sqlite3_backup_init()
** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or
** [sqlite3_errmsg16()] functions.
** ^A successful call to sqlite3_backup_init() returns a pointer to an
** [sqlite3_backup] object.
** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and
** sqlite3_backup_finish() functions to perform the specified backup
** operation.
**
** [[sqlite3_backup_step()]] <b>sqlite3_backup_step()</b>
**
** ^Function sqlite3_backup_step(B,N) will copy up to N pages between
** the source and destination databases specified by [sqlite3_backup] object B.
** ^If N is negative, all remaining source pages are copied.
** ^If sqlite3_backup_step(B,N) successfully copies N pages and there
** are still more pages to be copied, then the function returns [SQLITE_OK].
** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages
** from source to destination, then it returns [SQLITE_DONE].
** ^If an error occurs while running sqlite3_backup_step(B,N),
** then an [error code] is returned. ^As well as [SQLITE_OK] and
** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY],
** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an
** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code.
**
** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if
** <ol>
** <li> the destination database was opened read-only, or
** <li> the destination database is using write-ahead-log journaling
** and the destination and source page sizes differ, or
** <li> the destination database is an in-memory database and the
** destination and source page sizes differ.
** </ol>)^
**
** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then
** the [sqlite3_busy_handler | busy-handler function]
** is invoked (if one is specified). ^If the
** busy-handler returns non-zero before the lock is available, then
** [SQLITE_BUSY] is returned to the caller. ^In this case the call to
** sqlite3_backup_step() can be retried later. ^If the source
** [database connection]
** is being used to write to the source database when sqlite3_backup_step()
** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this
** case the call to sqlite3_backup_step() can be retried later on. ^(If
** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or
** [SQLITE_READONLY] is returned, then
** there is no point in retrying the call to sqlite3_backup_step(). These
** errors are considered fatal.)^ The application must accept
** that the backup operation has failed and pass the backup operation handle
** to the sqlite3_backup_finish() to release associated resources.
**
** ^The first call to sqlite3_backup_step() obtains an exclusive lock
** on the destination file. ^The exclusive lock is not released until either
** sqlite3_backup_finish() is called or the backup operation is complete
** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to
** sqlite3_backup_step() obtains a [shared lock] on the source database that
** lasts for the duration of the sqlite3_backup_step() call.
** ^Because the source database is not locked between calls to
** sqlite3_backup_step(), the source database may be modified mid-way
** through the backup process. ^If the source database is modified by an
** external process or via a database connection other than the one being
** used by the backup operation, then the backup will be automatically
** restarted by the next call to sqlite3_backup_step(). ^If the source
** database is modified by the using the same database connection as is used
** by the backup operation, then the backup database is automatically
** updated at the same time.
**
** [[sqlite3_backup_finish()]] <b>sqlite3_backup_finish()</b>
**
** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the
** application wishes to abandon the backup operation, the application
** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish().
** ^The sqlite3_backup_finish() interfaces releases all
** resources associated with the [sqlite3_backup] object.
** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any
** active write-transaction on the destination database is rolled back.
** The [sqlite3_backup] object is invalid
** and may not be used following a call to sqlite3_backup_finish().
**
** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no
** sqlite3_backup_step() errors occurred, regardless or whether or not
** sqlite3_backup_step() completed.
** ^If an out-of-memory condition or IO error occurred during any prior
** sqlite3_backup_step() call on the same [sqlite3_backup] object, then
** sqlite3_backup_finish() returns the corresponding [error code].
**
** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step()
** is not a permanent error and does not affect the return value of
** sqlite3_backup_finish().
**
** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]]
** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
**
** ^The sqlite3_backup_remaining() routine returns the number of pages still
** to be backed up at the conclusion of the most recent sqlite3_backup_step().
** ^The sqlite3_backup_pagecount() routine returns the total number of pages
** in the source database at the conclusion of the most recent
** sqlite3_backup_step().
** ^(The values returned by these functions are only updated by
** sqlite3_backup_step(). If the source database is modified in a way that
** changes the size of the source database or the number of pages remaining,
** those changes are not reflected in the output of sqlite3_backup_pagecount()
** and sqlite3_backup_remaining() until after the next
** sqlite3_backup_step().)^
**
** <b>Concurrent Usage of Database Handles</b>
**
** ^The source [database connection] may be used by the application for other
** purposes while a backup operation is underway or being initialized.
** ^If SQLite is compiled and configured to support threadsafe database
** connections, then the source database connection may be used concurrently
** from within other threads.
**
** However, the application must guarantee that the destination
** [database connection] is not passed to any other API (by any thread) after
** sqlite3_backup_init() is called and before the corresponding call to
** sqlite3_backup_finish(). SQLite does not currently check to see
** if the application incorrectly accesses the destination [database connection]
** and so no error code is reported, but the operations may malfunction
** nevertheless. Use of the destination database connection while a
** backup is in progress might also cause a mutex deadlock.
**
** If running in [shared cache mode], the application must
** guarantee that the shared cache used by the destination database
** is not accessed while the backup is running. In practice this means
** that the application must guarantee that the disk file being
** backed up to is not accessed by any connection within the process,
** not just the specific connection that was passed to sqlite3_backup_init().
**
** The [sqlite3_backup] object itself is partially threadsafe. Multiple
** threads may safely make multiple concurrent calls to sqlite3_backup_step().
** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount()
** APIs are not strictly speaking threadsafe. If they are invoked at the
** same time as another thread is invoking sqlite3_backup_step() it is
** possible that they return invalid values.
*/
SQLITE_API sqlite3_backup *sqlite3_backup_init(
sqlite3 *pDest, /* Destination database handle */
const char *zDestName, /* Destination database name */
sqlite3 *pSource, /* Source database handle */
const char *zSourceName /* Source database name */
);
SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
/*
** CAPI3REF: Unlock Notification
** METHOD: sqlite3
**
** ^When running in shared-cache mode, a database operation may fail with
** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
** individual tables within the shared-cache cannot be obtained. See
** [SQLite Shared-Cache Mode] for a description of shared-cache locking.
** ^This API may be used to register a callback that SQLite will invoke
** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will
** invoke sqlite3_free() on the serialization buffer when the database
** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then
** SQLite will try to increase the buffer size using sqlite3_realloc64()
** if writes on the database cause it to grow larger than M bytes.
**
** Applications must not modify the buffer P or invalidate it before
** the database connection D is closed.
**
** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the
** database is currently in a read transaction or is involved in a backup
** operation.
**
** It is not possible to deserialized into the TEMP database. If the
** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the
** function returns SQLITE_ERROR.
**
** The deserialized database should not be in [WAL mode]. If the database
** is in WAL mode, then any attempt to use the database file will result
** in an [SQLITE_CANTOPEN] error. The application can set the
** [file format version numbers] (bytes 18 and 19) of the input database P
sqlite3ext.h view on Meta::CPAN
void (*result_zeroblob)(sqlite3_context*,int);
void (*result_error_code)(sqlite3_context*,int);
int (*test_control)(int, ...);
void (*randomness)(int,void*);
sqlite3 *(*context_db_handle)(sqlite3_context*);
int (*extended_result_codes)(sqlite3*,int);
int (*limit)(sqlite3*,int,int);
sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
const char *(*sql)(sqlite3_stmt*);
int (*status)(int,int*,int*,int);
int (*backup_finish)(sqlite3_backup*);
sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*);
int (*backup_pagecount)(sqlite3_backup*);
int (*backup_remaining)(sqlite3_backup*);
int (*backup_step)(sqlite3_backup*,int);
const char *(*compileoption_get)(int);
int (*compileoption_used)(const char*);
int (*create_function_v2)(sqlite3*,const char*,int,int,void*,
void (*xFunc)(sqlite3_context*,int,sqlite3_value**),
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
void (*xFinal)(sqlite3_context*),
void(*xDestroy)(void*));
int (*db_config)(sqlite3*,int,...);
sqlite3_mutex *(*db_mutex)(sqlite3*);
int (*db_status)(sqlite3*,int,int*,int*,int);
sqlite3ext.h view on Meta::CPAN
#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob
#define sqlite3_result_error_code sqlite3_api->result_error_code
#define sqlite3_test_control sqlite3_api->test_control
#define sqlite3_randomness sqlite3_api->randomness
#define sqlite3_context_db_handle sqlite3_api->context_db_handle
#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes
#define sqlite3_limit sqlite3_api->limit
#define sqlite3_next_stmt sqlite3_api->next_stmt
#define sqlite3_sql sqlite3_api->sql
#define sqlite3_status sqlite3_api->status
#define sqlite3_backup_finish sqlite3_api->backup_finish
#define sqlite3_backup_init sqlite3_api->backup_init
#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount
#define sqlite3_backup_remaining sqlite3_api->backup_remaining
#define sqlite3_backup_step sqlite3_api->backup_step
#define sqlite3_compileoption_get sqlite3_api->compileoption_get
#define sqlite3_compileoption_used sqlite3_api->compileoption_used
#define sqlite3_create_function_v2 sqlite3_api->create_function_v2
#define sqlite3_db_config sqlite3_api->db_config
#define sqlite3_db_mutex sqlite3_api->db_mutex
#define sqlite3_db_status sqlite3_api->db_status
#define sqlite3_extended_errcode sqlite3_api->extended_errcode
#define sqlite3_log sqlite3_api->log
#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64
#define sqlite3_sourceid sqlite3_api->sourceid
t/34_online_backup.t view on Meta::CPAN
BEGIN { requires_sqlite('3.6.11') }
use if -d ".git", "Test::FailWarnings";
use DBI;
foreach my $call_func (@CALL_FUNCS) {
# Connect to the test db and add some stuff:
my $foo = connect_ok( dbfile => 'foo', RaiseError => 1 );
my $dbfile = dbfile('foo');
$foo->do(
'CREATE TABLE online_backup_test( id INTEGER PRIMARY KEY, foo INTEGER )'
);
$foo->do("INSERT INTO online_backup_test (foo) VALUES ($$)");
# That should be in the "foo" database on disk now, so disconnect and try to
# back it up:
$foo->disconnect;
my $dbh = DBI->connect(
'dbi:SQLite:dbname=:memory:',
undef, undef,
{ RaiseError => 1 }
);
ok($dbh->$call_func($dbfile, 'backup_from_file'));
{
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 file (foo):
ok($dbh->$call_func($dbfile, 'backup_to_file'));
$dbh->disconnect;
# Reconnect to foo db and check data made it over:
{
my $foo = connect_ok( dbfile => 'foo', RaiseError => 1 );
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;
}
$dbh->disconnect;
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;
}
done_testing;
t/rt_62370_diconnected_handles_operation.t view on Meta::CPAN
}
{
local $@;
eval { $dbh->$call_func(undef, 'set_authorizer') };
ok $@, "set authorizer dies with error: $@";
}
if ($DBD::SQLite::sqlite_version_number >= 3006011) {
local $@;
eval { $dbh->$call_func('./backup_file', 'backup_from_file') };
ok $@, "backup from file dies with error: $@";
}
if ($DBD::SQLite::sqlite_version_number >= 3006011) {
local $@;
eval { $dbh->$call_func('./backup_file', 'backup_to_file') };
ok $@, "backup to file dies with error: $@";
}
}
}
done_testing;
( run in 1.416 second using v1.01-cache-2.11-cpan-49f99fa48dc )