Fossil SCM

Record sync operations in the new synclog table.

drh 2021-12-19 17:50 trunk
Commit 42a6191e9366a2f156123e41b5b4f5d3e83c0e3d094056054b99ec0eae227dc0
--- src/export.c
+++ src/export.c
@@ -1370,10 +1370,11 @@
13701370
void gitmirror_export_command(void){
13711371
const char *zLimit; /* Text of the --limit flag */
13721372
int nLimit = 0x7fffffff; /* Numeric value of the --limit flag */
13731373
int nTotal = 0; /* Total number of check-ins to export */
13741374
char *zMirror; /* Name of the mirror */
1375
+ char *zMirrorAbs; /* Canonicalized name of the mirror */
13751376
char *z; /* Generic string */
13761377
char *zCmd; /* git command to run as a subprocess */
13771378
const char *zDebug = 0; /* Value of the --debug flag */
13781379
const char *zAutoPush = 0; /* Value of the --autopush flag */
13791380
char *zMainBr = 0; /* Value of the --mainbranch flag */
@@ -1696,10 +1697,15 @@
16961697
if( bNeedRepack ){
16971698
const char *zRepack = "git repack -adf";
16981699
gitmirror_message(VERB_NORMAL, "%s\n", zRepack);
16991700
fossil_system(zRepack);
17001701
}
1702
+
1703
+ /* Record this export into the sync log */
1704
+ zMirrorAbs = file_canonical_name_dup(zMirror);
1705
+ sync_log_entry(SYNC_PUSH, zMirrorAbs, "git");
1706
+ fossil_free(zMirrorAbs);
17011707
17021708
/* Optionally do a "git push" */
17031709
zPushUrl = db_text(0, "SELECT value FROM mconfig WHERE key='autopush'");
17041710
if( zPushUrl ){
17051711
char *zPushCmd;
@@ -1719,10 +1725,11 @@
17191725
}else if( db_is_writeable("repository") ){
17201726
db_unprotect(PROTECT_CONFIG);
17211727
db_multi_exec("REPLACE INTO config(name,value,mtime)"
17221728
"VALUES('gitpush:%q',1,now())", zPushUrl);
17231729
db_protect_pop();
1730
+ sync_log_entry(SYNC_PUSH, zPushUrl, "git-push");
17241731
}
17251732
fossil_free(zPushCmd);
17261733
}
17271734
}
17281735
17291736
--- src/export.c
+++ src/export.c
@@ -1370,10 +1370,11 @@
1370 void gitmirror_export_command(void){
1371 const char *zLimit; /* Text of the --limit flag */
1372 int nLimit = 0x7fffffff; /* Numeric value of the --limit flag */
1373 int nTotal = 0; /* Total number of check-ins to export */
1374 char *zMirror; /* Name of the mirror */
 
1375 char *z; /* Generic string */
1376 char *zCmd; /* git command to run as a subprocess */
1377 const char *zDebug = 0; /* Value of the --debug flag */
1378 const char *zAutoPush = 0; /* Value of the --autopush flag */
1379 char *zMainBr = 0; /* Value of the --mainbranch flag */
@@ -1696,10 +1697,15 @@
1696 if( bNeedRepack ){
1697 const char *zRepack = "git repack -adf";
1698 gitmirror_message(VERB_NORMAL, "%s\n", zRepack);
1699 fossil_system(zRepack);
1700 }
 
 
 
 
 
1701
1702 /* Optionally do a "git push" */
1703 zPushUrl = db_text(0, "SELECT value FROM mconfig WHERE key='autopush'");
1704 if( zPushUrl ){
1705 char *zPushCmd;
@@ -1719,10 +1725,11 @@
1719 }else if( db_is_writeable("repository") ){
1720 db_unprotect(PROTECT_CONFIG);
1721 db_multi_exec("REPLACE INTO config(name,value,mtime)"
1722 "VALUES('gitpush:%q',1,now())", zPushUrl);
1723 db_protect_pop();
 
1724 }
1725 fossil_free(zPushCmd);
1726 }
1727 }
1728
1729
--- src/export.c
+++ src/export.c
@@ -1370,10 +1370,11 @@
1370 void gitmirror_export_command(void){
1371 const char *zLimit; /* Text of the --limit flag */
1372 int nLimit = 0x7fffffff; /* Numeric value of the --limit flag */
1373 int nTotal = 0; /* Total number of check-ins to export */
1374 char *zMirror; /* Name of the mirror */
1375 char *zMirrorAbs; /* Canonicalized name of the mirror */
1376 char *z; /* Generic string */
1377 char *zCmd; /* git command to run as a subprocess */
1378 const char *zDebug = 0; /* Value of the --debug flag */
1379 const char *zAutoPush = 0; /* Value of the --autopush flag */
1380 char *zMainBr = 0; /* Value of the --mainbranch flag */
@@ -1696,10 +1697,15 @@
1697 if( bNeedRepack ){
1698 const char *zRepack = "git repack -adf";
1699 gitmirror_message(VERB_NORMAL, "%s\n", zRepack);
1700 fossil_system(zRepack);
1701 }
1702
1703 /* Record this export into the sync log */
1704 zMirrorAbs = file_canonical_name_dup(zMirror);
1705 sync_log_entry(SYNC_PUSH, zMirrorAbs, "git");
1706 fossil_free(zMirrorAbs);
1707
1708 /* Optionally do a "git push" */
1709 zPushUrl = db_text(0, "SELECT value FROM mconfig WHERE key='autopush'");
1710 if( zPushUrl ){
1711 char *zPushCmd;
@@ -1719,10 +1725,11 @@
1725 }else if( db_is_writeable("repository") ){
1726 db_unprotect(PROTECT_CONFIG);
1727 db_multi_exec("REPLACE INTO config(name,value,mtime)"
1728 "VALUES('gitpush:%q',1,now())", zPushUrl);
1729 db_protect_pop();
1730 sync_log_entry(SYNC_PUSH, zPushUrl, "git-push");
1731 }
1732 fossil_free(zPushCmd);
1733 }
1734 }
1735
1736
+24
--- src/schema.c
+++ src/schema.c
@@ -618,5 +618,29 @@
618618
void schema_forum(void){
619619
if( !db_table_exists("repository","forumpost") ){
620620
db_multi_exec("%s",zForumSchema/*safe-for-%s*/);
621621
}
622622
}
623
+
624
+/*
625
+** The following table holds information about servers with which
626
+** this repository has synced, as well as servers with which those
627
+** servers have synced, and so forth.
628
+*/
629
+static const char zSynclogSchema[] =
630
+@ CREATE TABLE repository.synclog(
631
+@ sfrom TEXT, -- Sync client. "self" means this repo
632
+@ sto TEXT, -- Sync server
633
+@ spush DATETIME, -- Time of last push (julian day)
634
+@ spull DATETIME, -- Time of last pull (julian day)
635
+@ sdist INT, -- Distance from this repo. 0 means self
636
+@ stype TEXT, -- Type of "sto". ex: "git","backup". NULL means fossil
637
+@ PRIMARY KEY(sfrom,sto)
638
+@ ) WITHOUT ROWID;
639
+;
640
+
641
+/* Create the forum-post schema if it does not already exist */
642
+void schema_synclog(void){
643
+ if( !db_table_exists("repository","synclog") ){
644
+ db_multi_exec("%s",zSynclogSchema/*safe-for-%s*/);
645
+ }
646
+}
623647
--- src/schema.c
+++ src/schema.c
@@ -618,5 +618,29 @@
618 void schema_forum(void){
619 if( !db_table_exists("repository","forumpost") ){
620 db_multi_exec("%s",zForumSchema/*safe-for-%s*/);
621 }
622 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
623
--- src/schema.c
+++ src/schema.c
@@ -618,5 +618,29 @@
618 void schema_forum(void){
619 if( !db_table_exists("repository","forumpost") ){
620 db_multi_exec("%s",zForumSchema/*safe-for-%s*/);
621 }
622 }
623
624 /*
625 ** The following table holds information about servers with which
626 ** this repository has synced, as well as servers with which those
627 ** servers have synced, and so forth.
628 */
629 static const char zSynclogSchema[] =
630 @ CREATE TABLE repository.synclog(
631 @ sfrom TEXT, -- Sync client. "self" means this repo
632 @ sto TEXT, -- Sync server
633 @ spush DATETIME, -- Time of last push (julian day)
634 @ spull DATETIME, -- Time of last pull (julian day)
635 @ sdist INT, -- Distance from this repo. 0 means self
636 @ stype TEXT, -- Type of "sto". ex: "git","backup". NULL means fossil
637 @ PRIMARY KEY(sfrom,sto)
638 @ ) WITHOUT ROWID;
639 ;
640
641 /* Create the forum-post schema if it does not already exist */
642 void schema_synclog(void){
643 if( !db_table_exists("repository","synclog") ){
644 db_multi_exec("%s",zSynclogSchema/*safe-for-%s*/);
645 }
646 }
647
+47
--- src/sync.c
+++ src/sync.c
@@ -92,10 +92,53 @@
9292
}
9393
fossil_free(azOther);
9494
return nErr;
9595
}
9696
97
+/*
98
+** Make a new entry, or update an existing entry, in the SYNCLOG table
99
+** for a push or pull from this repository to another server named zRemote.
100
+**
101
+** For an ordinary push/pull, zType is NULL. But it may also be a string
102
+** describing non-standard operations. For example zType might be "git"
103
+** when doing a "fossil git export", or zType might be "import" when doing
104
+** a "fossil pull --from-parent-project".
105
+**
106
+** For this routine, the sfrom value is always 'self'. The sto value is
107
+** the zRemote parameter. sto+sfrom form the primary key. If an entry
108
+** already exists with the same primary key, then the spull or spush times
109
+** are updated (or both).
110
+*/
111
+void sync_log_entry(
112
+ int syncFlags, /* Indicates whether a PUSH or PULL or both */
113
+ const char *zRemote, /* Server with which we push or pull */
114
+ const char *zType /* Type of sync. NULL for normal */
115
+){
116
+ const char *zPush;
117
+ const char *zPull;
118
+ if( syncFlags & (SYNC_PULL|SYNC_CLONE) ){
119
+ zPull = "julianday()";
120
+ }else{
121
+ zPull = "NULL";
122
+ }
123
+ if( syncFlags & (SYNC_PUSH) ){
124
+ zPush = "julianday()";
125
+ }else{
126
+ zPush = "NULL";
127
+ }
128
+ schema_synclog();
129
+ db_multi_exec(
130
+ "INSERT INTO repository.synclog(sfrom,sto,spush,spull,sdist,stype)"
131
+ " VALUES('self',%Q,%s,%s,0,%Q)"
132
+ " ON CONFLICT DO UPDATE"
133
+ " SET spush=coalesce(%s,spush),"
134
+ " spull=coalesce(%s,spull);",
135
+ zRemote, zPush/*safe-for-%s*/, zPull/*safe-for-%s*/, zType,
136
+ zPush/*safe-for-%s*/, zPull/*safe-for-%s*/
137
+ );
138
+}
139
+
97140
98141
/*
99142
** If the repository is configured for autosyncing, then do an
100143
** autosync. Bits of the "flags" parameter determine details of behavior:
101144
**
@@ -682,10 +725,11 @@
682725
** -R NAME Filename of the repository to backup
683726
*/
684727
void backup_cmd(void){
685728
char *zDest;
686729
int bOverwrite = 0;
730
+ char *zFullName;
687731
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
688732
bOverwrite = find_option("overwrite",0,0)!=0;
689733
verify_all_options();
690734
if( g.argc!=3 ){
691735
usage("FILE|DIRECTORY");
@@ -703,6 +747,9 @@
703747
fossil_fatal("backup \"%s\" already exists", zDest);
704748
}
705749
}
706750
db_unprotect(PROTECT_ALL);
707751
db_multi_exec("VACUUM repository INTO %Q", zDest);
752
+ zFullName = file_canonical_name_dup(zDest);
753
+ sync_log_entry(SYNC_PUSH, zFullName, "backup");
754
+ fossil_free(zFullName);
708755
}
709756
--- src/sync.c
+++ src/sync.c
@@ -92,10 +92,53 @@
92 }
93 fossil_free(azOther);
94 return nErr;
95 }
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
98 /*
99 ** If the repository is configured for autosyncing, then do an
100 ** autosync. Bits of the "flags" parameter determine details of behavior:
101 **
@@ -682,10 +725,11 @@
682 ** -R NAME Filename of the repository to backup
683 */
684 void backup_cmd(void){
685 char *zDest;
686 int bOverwrite = 0;
 
687 db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
688 bOverwrite = find_option("overwrite",0,0)!=0;
689 verify_all_options();
690 if( g.argc!=3 ){
691 usage("FILE|DIRECTORY");
@@ -703,6 +747,9 @@
703 fossil_fatal("backup \"%s\" already exists", zDest);
704 }
705 }
706 db_unprotect(PROTECT_ALL);
707 db_multi_exec("VACUUM repository INTO %Q", zDest);
 
 
 
708 }
709
--- src/sync.c
+++ src/sync.c
@@ -92,10 +92,53 @@
92 }
93 fossil_free(azOther);
94 return nErr;
95 }
96
97 /*
98 ** Make a new entry, or update an existing entry, in the SYNCLOG table
99 ** for a push or pull from this repository to another server named zRemote.
100 **
101 ** For an ordinary push/pull, zType is NULL. But it may also be a string
102 ** describing non-standard operations. For example zType might be "git"
103 ** when doing a "fossil git export", or zType might be "import" when doing
104 ** a "fossil pull --from-parent-project".
105 **
106 ** For this routine, the sfrom value is always 'self'. The sto value is
107 ** the zRemote parameter. sto+sfrom form the primary key. If an entry
108 ** already exists with the same primary key, then the spull or spush times
109 ** are updated (or both).
110 */
111 void sync_log_entry(
112 int syncFlags, /* Indicates whether a PUSH or PULL or both */
113 const char *zRemote, /* Server with which we push or pull */
114 const char *zType /* Type of sync. NULL for normal */
115 ){
116 const char *zPush;
117 const char *zPull;
118 if( syncFlags & (SYNC_PULL|SYNC_CLONE) ){
119 zPull = "julianday()";
120 }else{
121 zPull = "NULL";
122 }
123 if( syncFlags & (SYNC_PUSH) ){
124 zPush = "julianday()";
125 }else{
126 zPush = "NULL";
127 }
128 schema_synclog();
129 db_multi_exec(
130 "INSERT INTO repository.synclog(sfrom,sto,spush,spull,sdist,stype)"
131 " VALUES('self',%Q,%s,%s,0,%Q)"
132 " ON CONFLICT DO UPDATE"
133 " SET spush=coalesce(%s,spush),"
134 " spull=coalesce(%s,spull);",
135 zRemote, zPush/*safe-for-%s*/, zPull/*safe-for-%s*/, zType,
136 zPush/*safe-for-%s*/, zPull/*safe-for-%s*/
137 );
138 }
139
140
141 /*
142 ** If the repository is configured for autosyncing, then do an
143 ** autosync. Bits of the "flags" parameter determine details of behavior:
144 **
@@ -682,10 +725,11 @@
725 ** -R NAME Filename of the repository to backup
726 */
727 void backup_cmd(void){
728 char *zDest;
729 int bOverwrite = 0;
730 char *zFullName;
731 db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
732 bOverwrite = find_option("overwrite",0,0)!=0;
733 verify_all_options();
734 if( g.argc!=3 ){
735 usage("FILE|DIRECTORY");
@@ -703,6 +747,9 @@
747 fossil_fatal("backup \"%s\" already exists", zDest);
748 }
749 }
750 db_unprotect(PROTECT_ALL);
751 db_multi_exec("VACUUM repository INTO %Q", zDest);
752 zFullName = file_canonical_name_dup(zDest);
753 sync_log_entry(SYNC_PUSH, zFullName, "backup");
754 fossil_free(zFullName);
755 }
756
+16 -3
--- src/xfer.c
+++ src/xfer.c
@@ -1885,21 +1885,30 @@
18851885
const char *zClientId; /* A unique identifier for this check-out */
18861886
unsigned int mHttpFlags;/* Flags for the http_exchange() subsystem */
18871887
18881888
if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH;
18891889
if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE|SYNC_UNVERSIONED))==0
1890
- && configRcvMask==0 && configSendMask==0 ) return 0;
1890
+ && configRcvMask==0 && configSendMask==0 ){
1891
+ return 0;
1892
+ }
1893
+ if( zPCode==0 && (syncFlags & SYNC_CLONE)==0 ){
1894
+ /* Every established repository must have a project-code */
1895
+ fossil_fatal("no project-code defined for this repository");
1896
+ }
18911897
if( syncFlags & SYNC_FROMPARENT ){
18921898
configRcvMask = 0;
18931899
configSendMask = 0;
18941900
syncFlags &= ~(SYNC_PUSH);
1895
- zPCode = db_get("parent-project-code", 0);
1896
- if( zPCode==0 || db_get("parent-project-name",0)==0 ){
1901
+ zAltPCode = db_get("parent-project-code", 0);
1902
+ if( zAltPCode==0 || db_get("parent-project-name",0)==0 ){
18971903
fossil_fatal("there is no parent project: set the 'parent-project-code'"
18981904
" and 'parent-project-name' config parameters in order"
18991905
" to pull from a parent project");
19001906
}
1907
+ }
1908
+ if( zAltPCode!=0 && zPCode!=0 && sqlite3_stricmp(zPCode,zAltPCode)==0 ){
1909
+ zAltPCode = 0;
19011910
}
19021911
19031912
transport_stats(0, 0, 1);
19041913
socket_global_init();
19051914
memset(&xfer, 0, sizeof(xfer));
@@ -2682,10 +2691,14 @@
26822691
}else if( rSkew*24.0*3600.0 < -10.0 ){
26832692
fossil_warning("*** time skew *** server is slow by %s",
26842693
db_timespan_name(-rSkew));
26852694
g.clockSkewSeen = 1;
26862695
}
2696
+
2697
+ if( nErr==0 ){
2698
+ sync_log_entry(syncFlags, g.url.canonical, zAltPCode!=0 ? "import" : 0);
2699
+ }
26872700
26882701
fossil_force_newline();
26892702
fossil_print(
26902703
"%s done, wire bytes sent: %lld received: %lld ip: %s\n",
26912704
zOpType, nSent, nRcvd, g.zIpAddr);
26922705
--- src/xfer.c
+++ src/xfer.c
@@ -1885,21 +1885,30 @@
1885 const char *zClientId; /* A unique identifier for this check-out */
1886 unsigned int mHttpFlags;/* Flags for the http_exchange() subsystem */
1887
1888 if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH;
1889 if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE|SYNC_UNVERSIONED))==0
1890 && configRcvMask==0 && configSendMask==0 ) return 0;
 
 
 
 
 
 
1891 if( syncFlags & SYNC_FROMPARENT ){
1892 configRcvMask = 0;
1893 configSendMask = 0;
1894 syncFlags &= ~(SYNC_PUSH);
1895 zPCode = db_get("parent-project-code", 0);
1896 if( zPCode==0 || db_get("parent-project-name",0)==0 ){
1897 fossil_fatal("there is no parent project: set the 'parent-project-code'"
1898 " and 'parent-project-name' config parameters in order"
1899 " to pull from a parent project");
1900 }
 
 
 
1901 }
1902
1903 transport_stats(0, 0, 1);
1904 socket_global_init();
1905 memset(&xfer, 0, sizeof(xfer));
@@ -2682,10 +2691,14 @@
2682 }else if( rSkew*24.0*3600.0 < -10.0 ){
2683 fossil_warning("*** time skew *** server is slow by %s",
2684 db_timespan_name(-rSkew));
2685 g.clockSkewSeen = 1;
2686 }
 
 
 
 
2687
2688 fossil_force_newline();
2689 fossil_print(
2690 "%s done, wire bytes sent: %lld received: %lld ip: %s\n",
2691 zOpType, nSent, nRcvd, g.zIpAddr);
2692
--- src/xfer.c
+++ src/xfer.c
@@ -1885,21 +1885,30 @@
1885 const char *zClientId; /* A unique identifier for this check-out */
1886 unsigned int mHttpFlags;/* Flags for the http_exchange() subsystem */
1887
1888 if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH;
1889 if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE|SYNC_UNVERSIONED))==0
1890 && configRcvMask==0 && configSendMask==0 ){
1891 return 0;
1892 }
1893 if( zPCode==0 && (syncFlags & SYNC_CLONE)==0 ){
1894 /* Every established repository must have a project-code */
1895 fossil_fatal("no project-code defined for this repository");
1896 }
1897 if( syncFlags & SYNC_FROMPARENT ){
1898 configRcvMask = 0;
1899 configSendMask = 0;
1900 syncFlags &= ~(SYNC_PUSH);
1901 zAltPCode = db_get("parent-project-code", 0);
1902 if( zAltPCode==0 || db_get("parent-project-name",0)==0 ){
1903 fossil_fatal("there is no parent project: set the 'parent-project-code'"
1904 " and 'parent-project-name' config parameters in order"
1905 " to pull from a parent project");
1906 }
1907 }
1908 if( zAltPCode!=0 && zPCode!=0 && sqlite3_stricmp(zPCode,zAltPCode)==0 ){
1909 zAltPCode = 0;
1910 }
1911
1912 transport_stats(0, 0, 1);
1913 socket_global_init();
1914 memset(&xfer, 0, sizeof(xfer));
@@ -2682,10 +2691,14 @@
2691 }else if( rSkew*24.0*3600.0 < -10.0 ){
2692 fossil_warning("*** time skew *** server is slow by %s",
2693 db_timespan_name(-rSkew));
2694 g.clockSkewSeen = 1;
2695 }
2696
2697 if( nErr==0 ){
2698 sync_log_entry(syncFlags, g.url.canonical, zAltPCode!=0 ? "import" : 0);
2699 }
2700
2701 fossil_force_newline();
2702 fossil_print(
2703 "%s done, wire bytes sent: %lld received: %lld ip: %s\n",
2704 zOpType, nSent, nRcvd, g.zIpAddr);
2705

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button