Differences From
Artifact [7108d474]:
- File
src/db.c
— part of check-in
[9515143d]
at
2011-08-12 11:54:34
on branch trunk
— When forcing a rollback following an error, reset all SQL statement first
so that the rollback can be successful.
(user:
drh
size: 58038)
- File
src/db.c
— part of check-in
[3113f7b1]
at
2011-08-14 17:54:22
on branch ben-testing
— Remove the seperate versionable version of db_get(), which now uses ctrlSettings to determine whether a setting is versionable or not.
(user:
ben
size: 63330)
[more...]
1397 1397 void db_swap_connections(void){
1398 1398 if( !g.useAttach ){
1399 1399 sqlite3 *dbTemp = g.db;
1400 1400 g.db = g.dbConfig;
1401 1401 g.dbConfig = dbTemp;
1402 1402 }
1403 1403 }
1404 +
1405 +/*
1406 +** Logic for reading potentially versioned settings from
1407 +** .fossil-settings/<name> , and emits warnings if necessary.
1408 +** Returns the non-versioned value without modification if there is no
1409 +** versioned value.
1410 +*/
1411 +static char *db_get_do_versionable(const char *zName, char *zNonVersionedSetting){
1412 + /* Attempt to load the versioned setting from a checked out file */
1413 + char *zVersionedSetting = 0;
1414 + int noWarn = 0;
1415 +
1416 + if( db_open_local() ){
1417 + Blob versionedPathname;
1418 + char *zVersionedPathname;
1419 + blob_zero(&versionedPathname);
1420 + blob_appendf(&versionedPathname, "%s/.fossil-settings/%s",
1421 + g.zLocalRoot, zName);
1422 + zVersionedPathname = blob_str(&versionedPathname);
1423 + if( file_size(zVersionedPathname)>=0 ){
1424 + /* File exists, and contains the value for this setting. Load from
1425 + ** the file. */
1426 + Blob setting;
1427 + blob_zero(&setting);
1428 + if( blob_read_from_file(&setting, zVersionedPathname) >= 0 ){
1429 + blob_trim(&setting); /* Avoid non-obvious problems with line endings
1430 + ** on boolean properties */
1431 + zVersionedSetting = strdup(blob_str(&setting));
1432 + }
1433 + blob_reset(&setting);
1434 + /* See if there's a no-warn flag */
1435 + blob_append(&versionedPathname, ".no-warn", -1);
1436 + if( file_size(blob_str(&versionedPathname))>=0 ){
1437 + noWarn = 1;
1438 + }
1439 + }
1440 + blob_reset(&versionedPathname);
1441 + }
1442 + /* Display a warning? */
1443 + if( zVersionedSetting!=0 && zNonVersionedSetting!=0
1444 + && zNonVersionedSetting[0]!='\0' && !noWarn
1445 + ){
1446 + /* There's a versioned setting, and a non-versioned setting. Tell
1447 + ** the user about the conflict */
1448 + fossil_warning(
1449 + "setting %s has both versioned and non-versioned values: using "
1450 + "versioned value from file .fossil-settings/%s (to silence this "
1451 + "warning, either create an empty file named "
1452 + ".fossil-settings/%s.no-warn or delete the non-versioned setting "
1453 + " with \"fossil unset %s\")", zName, zName, zName, zName
1454 + );
1455 + }
1456 + /* Prefer the versioned setting */
1457 + return ( zVersionedSetting!=0 ) ? zVersionedSetting : zNonVersionedSetting;
1458 +}
1459 +
1404 1460
1405 1461 /*
1406 1462 ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the
1407 1463 ** repository and local databases.
1408 1464 */
1409 1465 char *db_get(const char *zName, char *zDefault){
1410 1466 char *z = 0;
1467 + int i;
1468 + const struct stControlSettings *ctrlSetting = 0;
1469 + /* Is this a setting? */
1470 + for(i=0; ctrlSettings[i].name; i++){
1471 + if( strcmp(ctrlSettings[i].name, zName)==0 ){
1472 + ctrlSetting = &(ctrlSettings[i]);
1473 + break;
1474 + }
1475 + }
1411 1476 if( g.repositoryOpen ){
1412 1477 z = db_text(0, "SELECT value FROM config WHERE name=%Q", zName);
1413 1478 }
1414 1479 if( z==0 && g.configOpen ){
1415 1480 db_swap_connections();
1416 1481 z = db_text(0, "SELECT value FROM global_config WHERE name=%Q", zName);
1417 1482 db_swap_connections();
1483 + }
1484 + if( ctrlSetting!=0 && ctrlSetting->versionable ){
1485 + /* This is a versionable setting, try and get the info from a checked out file */
1486 + z = db_get_do_versionable(zName, z);
1418 1487 }
1419 1488 if( z==0 ){
1420 1489 z = zDefault;
1421 1490 }
1422 1491 return z;
1423 1492 }
1424 1493 void db_set(const char *zName, const char *zValue, int globalFlag){
................................................................................
1601 1670 info_cmd();
1602 1671 }
1603 1672 }
1604 1673
1605 1674 /*
1606 1675 ** Print the value of a setting named zName
1607 1676 */
1608 -static void print_setting(const char *zName){
1677 +static void print_setting(const struct stControlSettings *ctrlSetting, int localOpen){
1609 1678 Stmt q;
1610 1679 if( g.repositoryOpen ){
1611 1680 db_prepare(&q,
1612 1681 "SELECT '(local)', value FROM config WHERE name=%Q"
1613 1682 " UNION ALL "
1614 1683 "SELECT '(global)', value FROM global_config WHERE name=%Q",
1615 - zName, zName
1684 + ctrlSetting->name, ctrlSetting->name
1616 1685 );
1617 1686 }else{
1618 1687 db_prepare(&q,
1619 1688 "SELECT '(global)', value FROM global_config WHERE name=%Q",
1620 - zName
1689 + ctrlSetting->name
1621 1690 );
1622 1691 }
1623 1692 if( db_step(&q)==SQLITE_ROW ){
1624 - fossil_print("%-20s %-8s %s\n", zName, db_column_text(&q, 0),
1693 + fossil_print("%-20s %-8s %s\n", ctrlSetting->name, db_column_text(&q, 0),
1625 1694 db_column_text(&q, 1));
1626 1695 }else{
1627 - fossil_print("%-20s\n", zName);
1696 + fossil_print("%-20s\n", ctrlSetting->name);
1697 + }
1698 + if( ctrlSetting->versionable && localOpen ){
1699 + /* Check to see if this is overridden by a versionable settings file */
1700 + Blob versionedPathname;
1701 + blob_zero(&versionedPathname);
1702 + blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", g.zLocalRoot, ctrlSetting->name);
1703 + if( file_size(blob_str(&versionedPathname))>=0 ){
1704 + fossil_print(" (overridden by contents of file .fossil-settings/%s)\n", ctrlSetting->name);
1705 + }
1628 1706 }
1629 1707 db_finalize(&q);
1630 1708 }
1631 1709
1632 1710
1633 1711 /*
1634 1712 ** define all settings, which can be controlled via the set/unset
................................................................................
1640 1718 ** set-commands and displays the 'set'-help as info.
1641 1719 */
1642 1720 #if INTERFACE
1643 1721 struct stControlSettings {
1644 1722 char const *name; /* Name of the setting */
1645 1723 char const *var; /* Internal variable name used by db_set() */
1646 1724 int width; /* Width of display. 0 for boolean values */
1725 + int versionable; /* Is this setting versionable? */
1647 1726 char const *def; /* Default value */
1648 1727 };
1649 1728 #endif /* INTERFACE */
1650 1729 struct stControlSettings const ctrlSettings[] = {
1651 - { "access-log", 0, 0, "off" },
1652 - { "auto-captcha", "autocaptcha", 0, "on" },
1653 - { "auto-shun", 0, 0, "on" },
1654 - { "autosync", 0, 0, "on" },
1655 - { "binary-glob", 0, 32, "" },
1656 - { "case-sensitive",0, 0, "on" },
1657 - { "clearsign", 0, 0, "off" },
1658 - { "crnl-glob", 0, 16, "" },
1659 - { "default-perms", 0, 16, "u" },
1660 - { "diff-command", 0, 16, "" },
1661 - { "dont-push", 0, 0, "off" },
1662 - { "editor", 0, 16, "" },
1663 - { "gdiff-command", 0, 16, "gdiff" },
1664 - { "gmerge-command",0, 40, "" },
1665 - { "https-login", 0, 0, "off" },
1666 - { "ignore-glob", 0, 40, "" },
1667 - { "http-port", 0, 16, "8080" },
1668 - { "localauth", 0, 0, "off" },
1669 - { "main-branch", 0, 40, "trunk" },
1670 - { "manifest", 0, 0, "off" },
1671 - { "max-upload", 0, 25, "250000" },
1672 - { "mtime-changes", 0, 0, "on" },
1673 - { "pgp-command", 0, 32, "gpg --clearsign -o " },
1674 - { "proxy", 0, 32, "off" },
1675 - { "repo-cksum", 0, 0, "on" },
1676 - { "self-register", 0, 0, "off" },
1677 - { "ssh-command", 0, 32, "" },
1678 - { "web-browser", 0, 32, "" },
1679 - { "white-foreground", 0, 0, "off" },
1680 - { 0,0,0,0 }
1730 + { "access-log", 0, 0, 0, "off" },
1731 + { "auto-captcha", "autocaptcha", 0, 0, "on" },
1732 + { "auto-shun", 0, 0, 0, "on" },
1733 + { "autosync", 0, 0, 0, "on" },
1734 + { "binary-glob", 0, 32, 1, "" },
1735 + { "clearsign", 0, 0, 0, "off" },
1736 + { "case-sensitive",0, 0, 0, "on" },
1737 + { "crnl-glob", 0, 16, 1, "" },
1738 + { "default-perms", 0, 16, 0, "u" },
1739 + { "diff-command", 0, 16, 0, "" },
1740 + { "dont-push", 0, 0, 0, "off" },
1741 + { "editor", 0, 16, 0, "" },
1742 + { "gdiff-command", 0, 16, 0, "gdiff" },
1743 + { "gmerge-command",0, 40, 0, "" },
1744 + { "https-login", 0, 0, 0, "off" },
1745 + { "ignore-glob", 0, 40, 1, "" },
1746 + { "empty-dirs", 0, 40, 1, "" },
1747 + { "http-port", 0, 16, 0, "8080" },
1748 + { "localauth", 0, 0, 0, "off" },
1749 + { "main-branch", 0, 40, 0, "trunk" },
1750 + { "manifest", 0, 0, 1, "off" },
1751 + { "max-upload", 0, 25, 0, "250000" },
1752 + { "mtime-changes", 0, 0, 0, "on" },
1753 + { "pgp-command", 0, 32, 0, "gpg --clearsign -o " },
1754 + { "proxy", 0, 32, 0, "off" },
1755 + { "relative-paths",0, 0, 0, "on" },
1756 + { "repo-cksum", 0, 0, 0, "on" },
1757 + { "self-register", 0, 0, 0, "off" },
1758 + { "ssl-ca-location",0, 40, 0, "" },
1759 + { "ssl-identity", 0, 40, 0, "" },
1760 + { "ssh-command", 0, 32, 0, "" },
1761 + { "web-browser", 0, 32, 0, "" },
1762 + { "white-foreground", 0, 0, 0, "off" },
1763 + { 0,0,0,0,0 }
1681 1764 };
1682 1765
1683 1766 /*
1684 1767 ** COMMAND: settings
1685 1768 ** COMMAND: unset
1686 1769 **
1687 1770 ** %fossil settings ?PROPERTY? ?VALUE? ?-global?
1688 1771 ** %fossil unset PROPERTY ?-global?
1689 1772 **
1690 1773 ** The "settings" command with no arguments lists all properties and their
1691 1774 ** values. With just a property name it shows the value of that property.
1692 1775 ** With a value argument it changes the property for the current repository.
1776 +**
1777 +** Settings marked as versionable are overridden by the contents of the
1778 +** file named .fossil-settings/PROPERTY in the checked out files, if that
1779 +** file exists.
1693 1780 **
1694 1781 ** The "unset" command clears a property setting.
1695 1782 **
1696 1783 **
1697 1784 ** auto-captcha If enabled, the Login page provides a button to
1698 1785 ** fill in the captcha password. Default: on
1699 1786 **
................................................................................
1703 1790 **
1704 1791 ** autosync If enabled, automatically pull prior to commit
1705 1792 ** or update and automatically push after commit or
1706 1793 ** tag or branch creation. If the value is "pullonly"
1707 1794 ** then only pull operations occur automatically.
1708 1795 ** Default: on
1709 1796 **
1710 -** binary-glob The VALUE is a comma-separated list of GLOB patterns
1711 -** that should be treated as binary files for merging
1712 -** purposes. Example: *.xml
1797 +** binary-glob The VALUE is a comma or newline-separated list of
1798 +** (versionable) GLOB patterns that should be treated as binary files
1799 +** for merging purposes. Example: *.xml
1713 1800 **
1714 1801 ** case-sensitive If TRUE, the files whose names differ only in case
1715 1802 ** care considered distinct. If FALSE files whose names
1716 1803 ** differ only in case are the same file. Defaults to
1717 1804 ** TRUE for unix and FALSE for windows and mac.
1718 1805 **
1719 1806 ** clearsign When enabled, fossil will attempt to sign all commits
1720 1807 ** with gpg. When disabled (the default), commits will
1721 1808 ** be unsigned. Default: off
1722 1809 **
1723 -** crnl-glob A comma-separated list of GLOB patterns for text files
1724 -** in which it is ok to have CR+NL line endings.
1810 +** crnl-glob A comma or newline-separated list of GLOB patterns for
1811 +** (versionable) text files in which it is ok to have CR+NL line endings.
1725 1812 ** Set to "*" to disable CR+NL checking.
1726 1813 **
1727 1814 ** default-perms Permissions given automatically to new users. For more
1728 1815 ** information on permissions see Users page in Server
1729 1816 ** Administration of the HTTP UI. Default: u.
1730 1817 **
1731 1818 ** diff-command External command to run when performing a diff.
1732 1819 ** If undefined, the internal text diff will be used.
1733 1820 **
1734 1821 ** dont-push Prevent this repository from pushing from client to
1735 1822 ** server. Useful when setting up a private branch.
1823 +**
1824 +** empty-dirs A comma or newline-separated list of pathnames. On
1825 +** (versionable) update and checkout commands, if no file or directory
1826 +** exists with that name, an empty directory will be
1827 +** created.
1736 1828 **
1737 1829 ** editor Text editor command used for check-in comments.
1738 1830 **
1739 1831 ** gdiff-command External command to run when performing a graphical
1740 1832 ** diff. If undefined, text diff will be used.
1741 1833 **
1742 1834 ** gmerge-command A graphical merge conflict resolver command operating
................................................................................
1747 1839 **
1748 1840 ** http-port The TCP/IP port number to use by the "server"
1749 1841 ** and "ui" commands. Default: 8080
1750 1842 **
1751 1843 ** https-login Send login creditials using HTTPS instead of HTTP
1752 1844 ** even if the login page request came via HTTP.
1753 1845 **
1754 -** ignore-glob The VALUE is a comma-separated list of GLOB patterns
1755 -** specifying files that the "extra" command will ignore.
1756 -** Example: *.o,*.obj,*.exe
1846 +** ignore-glob The VALUE is a comma or newline-separated list of GLOB
1847 +** (versionable) patterns specifying files that the "extra" command will
1848 +** ignore. Example: *.o,*.obj,*.exe
1757 1849 **
1758 1850 ** localauth If enabled, require that HTTP connections from
1759 1851 ** 127.0.0.1 be authenticated by password. If
1760 1852 ** false, all HTTP requests from localhost have
1761 1853 ** unrestricted access to the repository.
1762 1854 **
1763 1855 ** main-branch The primary branch for the project. Default: trunk
1764 1856 **
1765 1857 ** manifest If enabled, automatically create files "manifest" and
1766 -** "manifest.uuid" in every checkout. The SQLite and
1858 +** (versionable) "manifest.uuid" in every checkout. The SQLite and
1767 1859 ** Fossil repositories both require this. Default: off.
1768 1860 **
1769 1861 ** max-upload A limit on the size of uplink HTTP requests. The
1770 1862 ** default is 250000 bytes.
1771 1863 **
1772 1864 ** mtime-changes Use file modification times (mtimes) to detect when
1773 1865 ** files have been modified. (Default "on".)
................................................................................
1775 1867 ** pgp-command Command used to clear-sign manifests at check-in.
1776 1868 ** The default is "gpg --clearsign -o ".
1777 1869 **
1778 1870 ** proxy URL of the HTTP proxy. If undefined or "off" then
1779 1871 ** the "http_proxy" environment variable is consulted.
1780 1872 ** If the http_proxy environment variable is undefined
1781 1873 ** then a direct HTTP connection is used.
1874 +**
1875 +** relative-paths When showing changes and extras, report paths relative
1876 +** to the current working directory. Default: "on"
1782 1877 **
1783 1878 ** repo-cksum Compute checksums over all files in each checkout
1784 1879 ** as a double-check of correctness. Defaults to "on".
1785 1880 ** Disable on large repositories for a performance
1786 1881 ** improvement.
1787 1882 **
1788 1883 ** self-register Allow users to register themselves through the HTTP UI.
1789 1884 ** This is useful if you want to see other names than
1790 1885 ** "Anonymous" in e.g. ticketing system. On the other hand
1791 1886 ** users can not be deleted. Default: off.
1887 +**
1888 +** ssl-ca-location The full pathname to a file containing PEM encoded
1889 +** CA root certificates, or a directory of certificates
1890 +** with filenames formed from the certificate hashes as
1891 +** required by OpenSSL.
1892 +** If set, this will override the OS default list of
1893 +** OpenSSL CAs. If unset, the default list will be used.
1894 +** Some platforms may add additional certificates.
1895 +** Check your platform behaviour is as required if the
1896 +** exact contents of the CA root is critical for your
1897 +** application.
1898 +**
1899 +** ssl-identity The full pathname to a file containing a certificate
1900 +** and private key in PEM format. Create by concatenating
1901 +** the certificate and private key files.
1902 +** This identity will be presented to SSL servers to
1903 +** authenticate this client, in addition to the normal
1904 +** password authentication.
1792 1905 **
1793 1906 ** ssh-command Command used to talk to a remote machine with
1794 1907 ** the "ssh://" protocol.
1795 1908 **
1796 1909 ** web-browser A shell command used to launch your preferred
1797 1910 ** web browser when given a URL as an argument.
1798 1911 ** Defaults to "start" on windows, "open" on Mac,
................................................................................
1809 1922 if( !g.repositoryOpen ){
1810 1923 globalFlag = 1;
1811 1924 }
1812 1925 if( unsetFlag && g.argc!=3 ){
1813 1926 usage("PROPERTY ?-global?");
1814 1927 }
1815 1928 if( g.argc==2 ){
1929 + int openLocal = db_open_local();
1816 1930 for(i=0; ctrlSettings[i].name; i++){
1817 - print_setting(ctrlSettings[i].name);
1931 + print_setting(&ctrlSettings[i], openLocal);
1818 1932 }
1819 1933 }else if( g.argc==3 || g.argc==4 ){
1820 1934 const char *zName = g.argv[2];
1821 1935 int isManifest;
1822 1936 int n = strlen(zName);
1823 1937 for(i=0; ctrlSettings[i].name; i++){
1824 1938 if( strncmp(ctrlSettings[i].name, zName, n)==0 ) break;
................................................................................
1832 1946 }
1833 1947 if( unsetFlag ){
1834 1948 db_unset(ctrlSettings[i].name, globalFlag);
1835 1949 }else if( g.argc==4 ){
1836 1950 db_set(ctrlSettings[i].name, g.argv[3], globalFlag);
1837 1951 }else{
1838 1952 isManifest = 0;
1839 - print_setting(ctrlSettings[i].name);
1953 + print_setting(&ctrlSettings[i], db_open_local());
1840 1954 }
1841 1955 if( isManifest && g.localOpen ){
1842 1956 manifest_to_disk(db_lget_int("checkout", 0));
1843 1957 }
1844 1958 }else{
1845 1959 usage("?PROPERTY? ?VALUE?");
1846 1960 }