1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Fix the sqlite3_rsync utility so that it is able to synchronize a database

using a UTF16 text encoding.
[forum:/forumpost/e055d50821|Forum post e055d50821].

FossilOrigin-Name: 981347009c4baa9f16d60091d37e11b05a7fc1c62ae262c4de596b584d6a491a
This commit is contained in:
drh
2024-10-19 00:16:23 +00:00
parent a525d635a9
commit 78b6c17faa
3 changed files with 39 additions and 11 deletions

View File

@@ -56,6 +56,7 @@ struct SQLiteRsync {
u8 isRemote; /* On the remote side of a connection */
u8 isReplica; /* True if running on the replica side */
u8 iProtocol; /* Protocol version number */
u8 wrongEncoding; /* ATTACH failed due to wrong encoding */
sqlite3_uint64 nOut; /* Bytes transmitted */
sqlite3_uint64 nIn; /* Bytes received */
unsigned int nPage; /* Total number of pages in the database */
@@ -1064,7 +1065,15 @@ static sqlite3_stmt *prepareStmt(
return pStmt;
}
/* Run a single SQL statement
/* Run a single SQL statement. Report an error if something goes
** wrong.
**
** As a special case, if the statement starts with "ATTACH" (but not
** "Attach") and if the error message is about an incorrect encoding,
** then do not report the error, but instead set the wrongEncoding flag.
** This is a kludgy work-around to the problem of attaching a database
** with a non-UTF8 encoding to the empty :memory: database that is
** opened on the replica.
*/
static void runSql(SQLiteRsync *p, char *zSql, ...){
sqlite3_stmt *pStmt;
@@ -1077,8 +1086,15 @@ static void runSql(SQLiteRsync *p, char *zSql, ...){
int rc = sqlite3_step(pStmt);
if( rc==SQLITE_ROW ) rc = sqlite3_step(pStmt);
if( rc!=SQLITE_OK && rc!=SQLITE_DONE ){
reportError(p, "SQL statement [%s] failed: %s", zSql,
sqlite3_errmsg(p->db));
const char *zErr = sqlite3_errmsg(p->db);
if( strncmp(zSql,"ATTACH ", 7)==0
&& strstr(zErr,"must use the same text encoding")!=0
){
p->wrongEncoding = 1;
}else{
reportError(p, "SQL statement [%s] failed: %s", zSql,
sqlite3_errmsg(p->db));
}
}
sqlite3_finalize(pStmt);
}
@@ -1407,6 +1423,18 @@ static void replicaSide(SQLiteRsync *p){
break;
}
runSql(p, "ATTACH %Q AS 'replica'", p->zReplica);
if( p->wrongEncoding ){
p->wrongEncoding = 0;
runSql(p, "PRAGMA encoding=utf16le");
runSql(p, "VACUUM");
runSql(p, "ATTACH %Q AS 'replica'", p->zReplica);
if( p->wrongEncoding ){
p->wrongEncoding = 0;
runSql(p, "PRAGMA encoding=utf16be");
runSql(p, "VACUUM");
runSql(p, "Attach %Q AS 'replica'", p->zReplica);
}
}
if( p->nErr ){
closeDb(p);
break;