SQLite

Changes On Branch mistake
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch mistake Excluding Merge-Ins

This is equivalent to a diff from 873d4e274b to 9f88f73ce3

2025-05-01
16:07
Allow sqlite3_rsync to work on non-WAL-mode databases, as long as the --wal-only flag is not used. (Closed-Leaf check-in: e4126dcd1e user: drh tags: rsync-non-wal-mode)
16:02
Mistake: Started from the wrong check-out. (Leaf check-in: 9f88f73ce3 user: drh tags: mistake)
2025-02-20
16:47
Fix autoconf bundle to honor the --disable-static and --disable-shared flags, as reported in forum post ae5bd8a84b. Problem introduced in 3.49.0. (check-in: e5ea86dccf user: stephan tags: branch-3.49)
2025-02-18
13:38
Version 3.49.1 (check-in: 873d4e274b user: drh tags: release, branch-3.49, version-3.49.1)
2025-02-17
16:15
Add two generated files to the distclean rules of the autoconf bundle. (check-in: 57eceb361f user: stephan tags: branch-3.49)

Changes to tool/sqlite3_rsync.c.
31
32
33
34
35
36
37

38
39
40
41
42
43
44
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45







+







  "OPTIONS:\n"
  "\n"
  "   --exe PATH    Name of the sqlite3_rsync program on the remote side\n"
  "   --help        Show this help screen\n"
  "   --ssh PATH    Name of the SSH program used to reach the remote side\n"
  "   -v            Verbose.  Multiple v's for increasing output\n"
  "   --version     Show detailed version information\n"
  "   --wal-only    Do not sync unless both databases are in WAL mode\n"
;

typedef unsigned char u8;

/* Context for the run */
typedef struct SQLiteRsync SQLiteRsync;
struct SQLiteRsync {
53
54
55
56
57
58
59

60
61
62
63
64
65
66
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68







+







  int nWrErr;              /* Number of failed attempts to write on the pipe */
  u8 eVerbose;             /* Bigger for more output.  0 means none. */
  u8 bCommCheck;           /* True to debug the communication protocol */
  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 */
  u8 bWalOnly;             /* Require WAL mode */
  sqlite3_uint64 nOut;     /* Bytes transmitted */
  sqlite3_uint64 nIn;      /* Bytes received */
  unsigned int nPage;      /* Total number of pages in the database */
  unsigned int szPage;     /* Database page size */
  unsigned int nHashSent;  /* Hashes sent (replica to origin) */
  unsigned int nPageSent;  /* Page contents sent (origin to replica) */
};
1233
1234
1235
1236
1237
1238
1239

1240
1241
1242




1243
1244
1245
1246
1247
1248
1249
1235
1236
1237
1238
1239
1240
1241
1242



1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253







+
-
-
-
+
+
+
+







      reportError(p, "cannot open origin \"%s\": %s",
                  p->zOrigin, sqlite3_errmsg(p->db));
      closeDb(p);
      return;
    }
    hashRegister(p->db);
    runSql(p, "BEGIN");
    if( p->bWalOnly ){
    runSqlReturnText(p, buf, "PRAGMA journal_mode");
    if( sqlite3_stricmp(buf,"wal")!=0 ){
      reportError(p, "Origin database is not in WAL mode");
      runSqlReturnText(p, buf, "PRAGMA journal_mode");
      if( sqlite3_stricmp(buf,"wal")!=0 ){
        reportError(p, "Origin database is not in WAL mode");
      }
    }
    runSqlReturnUInt(p, &nPage, "PRAGMA page_count");
    runSqlReturnUInt(p, &szPg, "PRAGMA page_size");
  
    if( p->nErr==0 ){
      /* Send the ORIGIN_BEGIN message */
      writeByte(p, ORIGIN_BEGIN);
1459
1460
1461
1462
1463
1464
1465

1466
1467
1468
1469





1470
1471
1472
1473
1474
1475
1476
1463
1464
1465
1466
1467
1468
1469
1470




1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482







+
-
-
-
-
+
+
+
+
+







        }
        if( nRPage==0 ){
          runSql(p, "PRAGMA replica.page_size=%u", szOPage);
          runSql(p, "PRAGMA replica.journal_mode=WAL");
          runSql(p, "SELECT * FROM replica.sqlite_schema");
        }
        runSql(p, "BEGIN IMMEDIATE");
        if( p->bWalOnly ){
        runSqlReturnText(p, buf, "PRAGMA replica.journal_mode");
        if( strcmp(buf, "wal")!=0 ){
          reportError(p, "replica is not in WAL mode");
          break;
          runSqlReturnText(p, buf, "PRAGMA replica.journal_mode");
          if( strcmp(buf, "wal")!=0 ){
            reportError(p, "replica is not in WAL mode");
            break;
          }
        }
        runSqlReturnUInt(p, &nRPage, "PRAGMA replica.page_count");
        runSqlReturnUInt(p, &szRPage, "PRAGMA replica.page_size");
        if( szRPage!=szOPage ){
          reportError(p, "page size mismatch; origin is %d bytes and "
                         "replica is %d bytes", szOPage, szRPage);
          break;
1665
1666
1667
1668
1669
1670
1671

1672

1673
1674
1675
1676

1677
1678
1679
1680
1681
1682
1683
1684

1685
1686
1687
1688

1689
1690
1691
1692

1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704

1705
1706
1707
1708
1709
1710

1711
1712
1713
1714
1715




1716
1717
1718
1719
1720
1721
1722
1723

1724
1725
1726
1727
1728

1729
1730
1731
1732
1733
1734

1735
1736
1737
1738
1739
1740
1741
1671
1672
1673
1674
1675
1676
1677
1678

1679
1680
1681
1682

1683
1684
1685
1686
1687
1688
1689
1690

1691
1692
1693
1694

1695
1696
1697
1698

1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710

1711
1712
1713
1714
1715
1716

1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733

1734
1735
1736
1737
1738

1739
1740
1741
1742
1743
1744

1745
1746
1747
1748
1749
1750
1751
1752







+
-
+



-
+







-
+



-
+



-
+











-
+





-
+





+
+
+
+







-
+




-
+





-
+







  sqlite3_int64 tmElapse;
  const char *zRemoteErrFile = 0;

#define cli_opt_val cmdline_option_value(argc, argv, ++i)
  memset(&ctx, 0, sizeof(ctx));
  for(i=1; i<argc; i++){
    const char *z = argv[i];
    if( z[0]=='-' && z[1]=='-' && z[2]!=0 ) z++;
    if( strcmp(z,"--origin")==0 ){
    if( strcmp(z,"-origin")==0 ){
      isOrigin = 1;
      continue;
    }
    if( strcmp(z,"--replica")==0 ){
    if( strcmp(z,"-replica")==0 ){
      isReplica = 1;
      continue;
    }
    if( numVs(z) ){
      ctx.eVerbose += numVs(z);
      continue;
    }
    if( strcmp(z, "--ssh")==0 ){
    if( strcmp(z, "-ssh")==0 ){
      zSsh = cli_opt_val;
      continue;
    }
    if( strcmp(z, "--exe")==0 ){
    if( strcmp(z, "-exe")==0 ){
      zExe = cli_opt_val;
      continue;
    }
    if( strcmp(z, "--logfile")==0 ){
    if( strcmp(z, "-logfile")==0 ){
      /* DEBUG OPTION:  --logfile FILENAME
      ** Cause all local output traffic to be duplicated in FILENAME */
      const char *zLog = cli_opt_val;
      if( ctx.pLog ) fclose(ctx.pLog);
      ctx.pLog = fopen(zLog, "wb");
      if( ctx.pLog==0 ){
        fprintf(stderr, "cannot open \"%s\" for writing\n", argv[i]);
        return 1;
      }
      continue;
    }
    if( strcmp(z, "--errorfile")==0 ){
    if( strcmp(z, "-errorfile")==0 ){
      /* DEBUG OPTION:  --errorfile FILENAME
      ** Error messages on the local side are written into FILENAME */
      ctx.zErrFile = cli_opt_val;
      continue;
    }
    if( strcmp(z, "--remote-errorfile")==0 ){
    if( strcmp(z, "-remote-errorfile")==0 ){
      /* DEBUG OPTION:  --remote-errorfile FILENAME
      ** Error messages on the remote side are written into FILENAME on
      ** the remote side. */
      zRemoteErrFile = cli_opt_val;
      continue;
    }
    if( strcmp(z, "-wal-only")==0 ){
      ctx.bWalOnly = 1;
      continue;
    }
    if( strcmp(z, "-help")==0 || strcmp(z, "--help")==0
     || strcmp(z, "-?")==0
    ){
      printf("%s", zUsage);
      return 0;
    }
    if( strcmp(z, "--version")==0 ){
    if( strcmp(z, "-version")==0 ){
      printf("%s\n", sqlite3_sourceid());
      return 0;
    }
    if( z[0]=='-' ){
      if( strcmp(z,"--commcheck")==0 ){  /* DEBUG ONLY */
      if( strcmp(z,"-commcheck")==0 ){  /* DEBUG ONLY */
        /* Run a communication check with the remote side.  Do not attempt
        ** to exchange any database connection */
        ctx.bCommCheck = 1;
        continue;
      }
      if( strcmp(z,"--arg-escape-check")==0 ){  /* DEBUG ONLY */
      if( strcmp(z,"-arg-escape-check")==0 ){  /* DEBUG ONLY */
        /* Test the append_escaped_arg() routine by using it to render a
        ** copy of the input command-line, assuming all arguments except
        ** this one are filenames. */
        sqlite3_str *pStr = sqlite3_str_new(0);
        int k;
        for(k=0; k<argc; k++){
          append_escaped_arg(pStr, argv[k], i!=k);
1815
1816
1817
1818
1819
1820
1821



1822
1823
1824
1825
1826
1827
1828
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842







+
+
+







      append_escaped_arg(pStr, "--commcheck", 0);
      if( ctx.eVerbose==0 ) ctx.eVerbose = 1;
    }
    if( zRemoteErrFile ){
      append_escaped_arg(pStr, "--errorfile", 0);
      append_escaped_arg(pStr, zRemoteErrFile, 1);
    }
    if( ctx.bWalOnly ){
      append_escaped_arg(pStr, "--wal-only", 0);
    }
    append_escaped_arg(pStr, zDiv, 1);
    append_escaped_arg(pStr, file_tail(ctx.zReplica), 1);
    zCmd = sqlite3_str_finish(pStr);
    if( ctx.eVerbose>=2 ) printf("%s\n", zCmd);
    if( popen2(zCmd, &ctx.pIn, &ctx.pOut, &childPid, 0) ){
      fprintf(stderr, "Could not start auxiliary process: %s\n", zCmd);
      return 1;