| | @@ -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 |
| | @@ -1206,23 +1221,51 @@ |
| 1206 | 1221 | "INSERT INTO user(login,pw,cap,info)" |
| 1207 | 1222 | " VALUES('reader','','kptw','Reader');" |
| 1208 | 1223 | ); |
| 1209 | 1224 | } |
| 1210 | 1225 | } |
| 1226 | + |
| 1227 | +/* |
| 1228 | +** Return a pointer to a string that contains the RHS of an IN operator |
| 1229 | +** that will select CONFIG table names that are in the list of control |
| 1230 | +** settings. |
| 1231 | +*/ |
| 1232 | +const char *db_setting_inop_rhs(){ |
| 1233 | + Blob x; |
| 1234 | + int i; |
| 1235 | + const char *zSep = ""; |
| 1236 | + |
| 1237 | + blob_zero(&x); |
| 1238 | + blob_append(&x, "(", 1); |
| 1239 | + for(i=0; ctrlSettings[i].name; i++){ |
| 1240 | + blob_appendf(&x, "%s'%s'", zSep, ctrlSettings[i].name); |
| 1241 | + zSep = ","; |
| 1242 | + } |
| 1243 | + blob_append(&x, ")", 1); |
| 1244 | + return blob_str(&x); |
| 1245 | +} |
| 1211 | 1246 | |
| 1212 | 1247 | /* |
| 1213 | 1248 | ** Fill an empty repository database with the basic information for a |
| 1214 | 1249 | ** repository. This function is shared between 'create_repository_cmd' |
| 1215 | 1250 | ** ('new') and 'reconstruct_cmd' ('reconstruct'), both of which create |
| 1216 | 1251 | ** new repositories. |
| 1252 | +** |
| 1253 | +** The zTemplate parameter determines if the settings for the repository |
| 1254 | +** should be copied from another repository. If zTemplate is 0 then the |
| 1255 | +** settings will have their normal default values. If zTemplate is |
| 1256 | +** non-zero, it is assumed that the caller of this function has already |
| 1257 | +** attached a database using the label "settingSrc". If not, the call to |
| 1258 | +** this function will fail. |
| 1217 | 1259 | ** |
| 1218 | 1260 | ** The zInitialDate parameter determines the date of the initial check-in |
| 1219 | 1261 | ** that is automatically created. If zInitialDate is 0 then no initial |
| 1220 | 1262 | ** check-in is created. The makeServerCodes flag determines whether or |
| 1221 | 1263 | ** not server and project codes are invented for this repository. |
| 1222 | 1264 | */ |
| 1223 | 1265 | void db_initial_setup( |
| 1266 | + const char *zTemplate, /* Repository from which to copy settings. */ |
| 1224 | 1267 | const char *zInitialDate, /* Initial date of repository. (ex: "now") */ |
| 1225 | 1268 | const char *zDefaultUser, /* Default user for the repository */ |
| 1226 | 1269 | int makeServerCodes /* True to make new server & project codes */ |
| 1227 | 1270 | ){ |
| 1228 | 1271 | char *zDate; |
| | @@ -1241,10 +1284,47 @@ |
| 1241 | 1284 | } |
| 1242 | 1285 | if( !db_is_global("autosync") ) db_set_int("autosync", 1, 0); |
| 1243 | 1286 | if( !db_is_global("localauth") ) db_set_int("localauth", 0, 0); |
| 1244 | 1287 | db_create_default_users(0, zDefaultUser); |
| 1245 | 1288 | user_select(); |
| 1289 | + |
| 1290 | + if( zTemplate ){ |
| 1291 | + /* |
| 1292 | + ** Copy all settings from the supplied template repository. |
| 1293 | + */ |
| 1294 | + db_multi_exec( |
| 1295 | + "INSERT OR REPLACE INTO config" |
| 1296 | + " SELECT name,value,mtime FROM settingSrc.config" |
| 1297 | + " WHERE (name IN %s OR name IN %s)" |
| 1298 | + " AND name NOT GLOB 'project-*';", |
| 1299 | + configure_inop_rhs(CONFIGSET_ALL), |
| 1300 | + db_setting_inop_rhs() |
| 1301 | + ); |
| 1302 | + db_multi_exec( |
| 1303 | + "REPLACE INTO reportfmt SELECT * FROM settingSrc.reportfmt;" |
| 1304 | + ); |
| 1305 | + |
| 1306 | + /* |
| 1307 | + ** Copy the user permissions, contact information, last modified |
| 1308 | + ** time, and photo for all the "system" users from the supplied |
| 1309 | + ** template repository into the one being setup. The other columns |
| 1310 | + ** are not copied because they contain security information or other |
| 1311 | + ** data specific to the other repository. The list of columns copied |
| 1312 | + ** by this SQL statement may need to be revised in the future. |
| 1313 | + */ |
| 1314 | + db_multi_exec("UPDATE user SET" |
| 1315 | + " cap = (SELECT u2.cap FROM settingSrc.user u2" |
| 1316 | + " WHERE u2.login = user.login)," |
| 1317 | + " info = (SELECT u2.info FROM settingSrc.user u2" |
| 1318 | + " WHERE u2.login = user.login)," |
| 1319 | + " mtime = (SELECT u2.mtime FROM settingSrc.user u2" |
| 1320 | + " WHERE u2.login = user.login)," |
| 1321 | + " photo = (SELECT u2.photo FROM settingSrc.user u2" |
| 1322 | + " WHERE u2.login = user.login)" |
| 1323 | + " WHERE user.login IN ('anonymous','nobody','developer','reader');" |
| 1324 | + ); |
| 1325 | + } |
| 1246 | 1326 | |
| 1247 | 1327 | if( zInitialDate ){ |
| 1248 | 1328 | int rid; |
| 1249 | 1329 | blob_zero(&manifest); |
| 1250 | 1330 | blob_appendf(&manifest, "C initial\\sempty\\scheck-in\n"); |
| | @@ -1277,33 +1357,47 @@ |
| 1277 | 1357 | ** |
| 1278 | 1358 | ** By default, your current login name is used to create the default |
| 1279 | 1359 | ** admin user. This can be overridden using the -A|--admin-user |
| 1280 | 1360 | ** parameter. |
| 1281 | 1361 | ** |
| 1362 | +** By default, all settings will be initialized to their default values. |
| 1363 | +** This can be overridden using the --template parameter to specify a |
| 1364 | +** repository file from which to copy the initial settings. When a template |
| 1365 | +** repository is used, almost all of the settings accessible from the setup |
| 1366 | +** page, either directly or indirectly, will be copied. Normal users and |
| 1367 | +** their associated permissions will not be copied; however, the system |
| 1368 | +** default users "anonymous", "nobody", "reader", "developer", and their |
| 1369 | +** associated permissions will be copied. |
| 1370 | +** |
| 1282 | 1371 | ** Options: |
| 1372 | +** --template FILE copy settings from repository file |
| 1283 | 1373 | ** --admin-user|-A USERNAME select given USERNAME as admin user |
| 1284 | 1374 | ** --date-override DATETIME use DATETIME as time of the initial checkin |
| 1285 | 1375 | ** |
| 1286 | 1376 | ** See also: clone |
| 1287 | 1377 | */ |
| 1288 | 1378 | void create_repository_cmd(void){ |
| 1289 | 1379 | char *zPassword; |
| 1380 | + const char *zTemplate; /* Repository from which to copy settings */ |
| 1290 | 1381 | const char *zDate; /* Date of the initial check-in */ |
| 1291 | 1382 | const char *zDefaultUser; /* Optional name of the default user */ |
| 1292 | 1383 | |
| 1384 | + zTemplate = find_option("template",0,1); |
| 1293 | 1385 | zDate = find_option("date-override",0,1); |
| 1294 | 1386 | zDefaultUser = find_option("admin-user","A",1); |
| 1295 | 1387 | if( zDate==0 ) zDate = "now"; |
| 1296 | 1388 | if( g.argc!=3 ){ |
| 1297 | 1389 | usage("REPOSITORY-NAME"); |
| 1298 | 1390 | } |
| 1299 | 1391 | db_create_repository(g.argv[2]); |
| 1300 | 1392 | db_open_repository(g.argv[2]); |
| 1301 | 1393 | db_open_config(0); |
| 1394 | + if( zTemplate ) db_attach(zTemplate, "settingSrc"); |
| 1302 | 1395 | db_begin_transaction(); |
| 1303 | | - db_initial_setup(zDate, zDefaultUser, 1); |
| 1396 | + db_initial_setup(zTemplate, zDate, zDefaultUser, 1); |
| 1304 | 1397 | db_end_transaction(0); |
| 1398 | + if( zTemplate ) db_detach("settingSrc"); |
| 1305 | 1399 | fossil_print("project-id: %s\n", db_get("project-code", 0)); |
| 1306 | 1400 | fossil_print("server-id: %s\n", db_get("server-code", 0)); |
| 1307 | 1401 | zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); |
| 1308 | 1402 | fossil_print("admin-user: %s (initial password is \"%s\")\n", |
| 1309 | 1403 | g.zLogin, zPassword); |
| 1310 | 1404 | |