| | @@ -701,10 +701,25 @@ |
| 701 | 701 | sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */ |
| 702 | 702 | sqlite3_create_function(db, "now", 0, SQLITE_ANY, 0, db_now_function, 0, 0); |
| 703 | 703 | return db; |
| 704 | 704 | } |
| 705 | 705 | |
| 706 | + |
| 707 | +/* |
| 708 | +** Detaches the zLabel database. |
| 709 | +*/ |
| 710 | +void db_detach(const char *zLabel){ |
| 711 | + db_multi_exec("DETACH DATABASE %s", zLabel); |
| 712 | +} |
| 713 | + |
| 714 | +/* |
| 715 | +** zDbName is the name of a database file. Attach zDbName using |
| 716 | +** the name zLabel. |
| 717 | +*/ |
| 718 | +void db_attach(const char *zDbName, const char *zLabel){ |
| 719 | + db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel); |
| 720 | +} |
| 706 | 721 | |
| 707 | 722 | /* |
| 708 | 723 | ** zDbName is the name of a database file. If no other database |
| 709 | 724 | ** file is open, then open this one. If another database file is |
| 710 | 725 | ** already open, then attach zDbName using the name zLabel. |
| | @@ -713,11 +728,11 @@ |
| 713 | 728 | if( !g.db ){ |
| 714 | 729 | g.db = openDatabase(zDbName); |
| 715 | 730 | g.zMainDbType = zLabel; |
| 716 | 731 | db_connection_init(); |
| 717 | 732 | }else{ |
| 718 | | - db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel); |
| 733 | + db_attach(zDbName, zLabel); |
| 719 | 734 | } |
| 720 | 735 | } |
| 721 | 736 | |
| 722 | 737 | /* |
| 723 | 738 | ** Open the user database in "~/.fossil". Create the database anew if |
| | @@ -1212,17 +1227,25 @@ |
| 1212 | 1227 | /* |
| 1213 | 1228 | ** Fill an empty repository database with the basic information for a |
| 1214 | 1229 | ** repository. This function is shared between 'create_repository_cmd' |
| 1215 | 1230 | ** ('new') and 'reconstruct_cmd' ('reconstruct'), both of which create |
| 1216 | 1231 | ** new repositories. |
| 1232 | +** |
| 1233 | +** The zTemplate parameter determines if the settings for the repository |
| 1234 | +** should be copied from another repository. If zTemplate is 0 then the |
| 1235 | +** settings will have their normal default values. If zTemplate is |
| 1236 | +** non-zero, it is assumed that the caller of this function has already |
| 1237 | +** attached a database using the label "settingSrc". If not, the call to |
| 1238 | +** this function will fail. |
| 1217 | 1239 | ** |
| 1218 | 1240 | ** The zInitialDate parameter determines the date of the initial check-in |
| 1219 | 1241 | ** that is automatically created. If zInitialDate is 0 then no initial |
| 1220 | 1242 | ** check-in is created. The makeServerCodes flag determines whether or |
| 1221 | 1243 | ** not server and project codes are invented for this repository. |
| 1222 | 1244 | */ |
| 1223 | 1245 | void db_initial_setup( |
| 1246 | + const char *zTemplate, /* Repository from which to copy settings. */ |
| 1224 | 1247 | const char *zInitialDate, /* Initial date of repository. (ex: "now") */ |
| 1225 | 1248 | const char *zDefaultUser, /* Default user for the repository */ |
| 1226 | 1249 | int makeServerCodes /* True to make new server & project codes */ |
| 1227 | 1250 | ){ |
| 1228 | 1251 | char *zDate; |
| | @@ -1241,10 +1264,53 @@ |
| 1241 | 1264 | } |
| 1242 | 1265 | if( !db_is_global("autosync") ) db_set_int("autosync", 1, 0); |
| 1243 | 1266 | if( !db_is_global("localauth") ) db_set_int("localauth", 0, 0); |
| 1244 | 1267 | db_create_default_users(0, zDefaultUser); |
| 1245 | 1268 | user_select(); |
| 1269 | + |
| 1270 | + if( zTemplate ){ |
| 1271 | + /* |
| 1272 | + ** Copy all settings from the supplied template repository |
| 1273 | + ** except those that are, by definition, always unique to a |
| 1274 | + ** specific project. The list of settings excluded by this |
| 1275 | + ** SQL statement may need to be revised in the future. |
| 1276 | + */ |
| 1277 | + db_multi_exec( |
| 1278 | + "INSERT OR REPLACE INTO config" |
| 1279 | + " SELECT name,value,mtime" |
| 1280 | + " FROM settingSrc.config WHERE name NOT IN (" |
| 1281 | + " 'content-schema','aux-schema'," |
| 1282 | + " 'server-code','project-code'," |
| 1283 | + " 'last-sync-url','last-sync-pw'," |
| 1284 | + " 'captcha-secret','login-group-code'," |
| 1285 | + " 'login-group-name'" |
| 1286 | + " ) AND " |
| 1287 | + " name NOT GLOB 'ckout:*' AND" |
| 1288 | + " name NOT GLOB 'baseurl:*' AND" |
| 1289 | + " name NOT GLOB 'peer-name-*' AND" |
| 1290 | + " name NOT GLOB 'peer-repo-*';" |
| 1291 | + ); |
| 1292 | + /* |
| 1293 | + ** Copy the user permissions, contact information, last modified |
| 1294 | + ** time, and photo for all the "system" users from the supplied |
| 1295 | + ** template repository into the one being setup. The other columns |
| 1296 | + ** are not copied because they contain security information or other |
| 1297 | + ** data specific to the other repository. The list of columns copied |
| 1298 | + ** by this SQL statement may need to be revised in the future. |
| 1299 | + */ |
| 1300 | + db_multi_exec("UPDATE user SET" |
| 1301 | + " cap = (SELECT u2.cap FROM settingSrc.user u2" |
| 1302 | + " WHERE u2.login = login)," |
| 1303 | + " info = (SELECT u2.info FROM settingSrc.user u2" |
| 1304 | + " WHERE u2.login = login)," |
| 1305 | + " mtime = (SELECT u2.mtime FROM settingSrc.user u2" |
| 1306 | + " WHERE u2.login = login)," |
| 1307 | + " photo = (SELECT u2.photo FROM settingSrc.user u2" |
| 1308 | + " WHERE u2.login = login)" |
| 1309 | + " WHERE login IN ('anonymous','nobody','developer','reader');" |
| 1310 | + ); |
| 1311 | + } |
| 1246 | 1312 | |
| 1247 | 1313 | if( zInitialDate ){ |
| 1248 | 1314 | int rid; |
| 1249 | 1315 | blob_zero(&manifest); |
| 1250 | 1316 | blob_appendf(&manifest, "C initial\\sempty\\scheck-in\n"); |
| | @@ -1277,33 +1343,47 @@ |
| 1277 | 1343 | ** |
| 1278 | 1344 | ** By default, your current login name is used to create the default |
| 1279 | 1345 | ** admin user. This can be overridden using the -A|--admin-user |
| 1280 | 1346 | ** parameter. |
| 1281 | 1347 | ** |
| 1348 | +** By default, all settings will be initialized to their default values. |
| 1349 | +** This can be overridden using the --template parameter to specify a |
| 1350 | +** repository file from which to copy the initial settings. When a template |
| 1351 | +** repository is used, almost all of the settings accessible from the setup |
| 1352 | +** page, either directly or indirectly, will be copied. Normal users and |
| 1353 | +** their associated permissions will not be copied; however, the system |
| 1354 | +** default users "anonymous", "nobody", "reader", "developer", and their |
| 1355 | +** associated permissions will be copied. |
| 1356 | +** |
| 1282 | 1357 | ** Options: |
| 1358 | +** --template FILE copy settings from repository file |
| 1283 | 1359 | ** --admin-user|-A USERNAME select given USERNAME as admin user |
| 1284 | 1360 | ** --date-override DATETIME use DATETIME as time of the initial checkin |
| 1285 | 1361 | ** |
| 1286 | 1362 | ** See also: clone |
| 1287 | 1363 | */ |
| 1288 | 1364 | void create_repository_cmd(void){ |
| 1289 | 1365 | char *zPassword; |
| 1366 | + const char *zTemplate; /* Repository from which to copy settings */ |
| 1290 | 1367 | const char *zDate; /* Date of the initial check-in */ |
| 1291 | 1368 | const char *zDefaultUser; /* Optional name of the default user */ |
| 1292 | 1369 | |
| 1370 | + zTemplate = find_option("template",0,1); |
| 1293 | 1371 | zDate = find_option("date-override",0,1); |
| 1294 | 1372 | zDefaultUser = find_option("admin-user","A",1); |
| 1295 | 1373 | if( zDate==0 ) zDate = "now"; |
| 1296 | 1374 | if( g.argc!=3 ){ |
| 1297 | 1375 | usage("REPOSITORY-NAME"); |
| 1298 | 1376 | } |
| 1299 | 1377 | db_create_repository(g.argv[2]); |
| 1300 | 1378 | db_open_repository(g.argv[2]); |
| 1301 | 1379 | db_open_config(0); |
| 1380 | + if( zTemplate ) db_attach(zTemplate, "settingSrc"); |
| 1302 | 1381 | db_begin_transaction(); |
| 1303 | | - db_initial_setup(zDate, zDefaultUser, 1); |
| 1382 | + db_initial_setup(zTemplate, zDate, zDefaultUser, 1); |
| 1304 | 1383 | db_end_transaction(0); |
| 1384 | + if( zTemplate ) db_detach("settingSrc"); |
| 1305 | 1385 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 1306 | 1386 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 1307 | 1387 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 1308 | 1388 | fossil_print("admin-user: %s (initial password is \"%s\")\n", |
| 1309 | 1389 | g.zLogin, zPassword); |
| 1310 | 1390 | |