Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | More char-to-bool conversions. Moved fsl_stmt_bind_fmt() into the public API and added a basic test for it. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d386e0d741305d83ba7783def38accaa |
User & Date: | stephan 2021-03-05 07:43:08.649 |
Context
2021-03-05
| ||
07:52 | fsl_content_put_ex() automatically rejects any blobs over a certain size (close to 2GB) for compatibility with fossil, which has a hard-coded limit of 2GB via its use of int-sized numbers for all ranges and access to blobs. fsl_buffers may exceed that, but such blobs may not be put into the db, lest we add something to the repo which will cause on OOM error for fossil. check-in: 633bf431cd user: stephan tags: trunk | |
07:43 | More char-to-bool conversions. Moved fsl_stmt_bind_fmt() into the public API and added a basic test for it. check-in: d386e0d741 user: stephan tags: trunk | |
06:00 | f-open and f-co now (mostly) honor --quiet. f-co now deletes files which removed between the original and target checkin unless the --no-rm flag is used. f-co cowardly refuses to check out the same version over itself. BUG: i have seen a few instances where the vvar 'checkout' setting disappears, leading to later app calls saying it's 'not a checkout', but have yet to pin down the origin. check-in: da6bcc64ba user: stephan tags: trunk | |
Changes
Changes to f-apps/f-sanity.c.
︙ | ︙ | |||
1682 1683 1684 1685 1686 1687 1688 | assert(fsl_str_is_date2(d)>0); ++d; assert(fsl_str_is_date2(d)<0); ++d; assert(!fsl_str_is_date2(d)); } | | | | 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 | assert(fsl_str_is_date2(d)>0); ++d; assert(fsl_str_is_date2(d)<0); ++d; assert(!fsl_str_is_date2(d)); } static void test_vpath_1(){ fsl_cx * f = fcli_cx(); fsl_vpath p = fsl_vpath_empty; fsl_vpath_node * n; int rc; fsl_id_t v1, v2; char oneWayOnly, directOnly; char const * sym1 = "c10d7424ae4c"; char const * sym2 = "d7927376fa9d"; /* d7927376fa9d is 3 versions after c10d7424ae4c. */ if(1){ /* swap version order */ char const * x = sym1; sym1 = sym2; sym2 = x; } f_out("test_vpath_1()...\n"); if(0){ sym1 = "99237c363673"; v1 = 1; }else{ rc = fsl_sym_to_rid(f, sym1, FSL_SATYPE_CHECKIN, &v1); assert(0==rc); |
︙ | ︙ | |||
1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 | #undef jcheck } #endif /* FSLPRINTF_ENABLE_JSON */ /* static */ void test_repo_is_readonly(){ /* TODO */ } int main(int argc, char const * const * argv ){ int rc = 0; fsl_cx * f; bool singleTest = false; fsl_timer_state timer = fsl_timer_state_empty; fsl_timer_start(&timer); | > > > > > > > > > > > > > > > > > | 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 | #undef jcheck } #endif /* FSLPRINTF_ENABLE_JSON */ /* static */ void test_repo_is_readonly(){ /* TODO */ } void test_bind_fmt(){ fsl_cx * f = fcli_cx(); fsl_db * db = fsl_cx_db(f); fsl_stmt q = fsl_stmt_empty; int rc; f_out("%s() fsl_stmt_bind_fmt() tests\n", __func__); rc = fsl_db_prepare(db, &q, "SELECT ? as X UNION SELECT ? UNION SELECT ?"); assert(0==rc); rc = fsl_stmt_bind_fmt(&q, "ifs", (int)42, (double)42.24, "Fourty two"); assert(0==rc); rc = fsl_stmt_each(&q, fsl_stmt_each_f_dump, NULL); assert(0==rc); fsl_stmt_finalize(&q); } int main(int argc, char const * const * argv ){ int rc = 0; fsl_cx * f; bool singleTest = false; fsl_timer_state timer = fsl_timer_state_empty; fsl_timer_start(&timer); |
︙ | ︙ | |||
1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 | test_versionable_config(); test_cx_glob_lists(); test_import_blob(); test_date2(); #if FSLPRINTF_ENABLE_JSON test_printf_json(); #endif if(0) test_simplify_sql(); } }else{ /* placeholder for use while developing tests. */ if(0) test_repo_extract(); if(0) test_gradient(); | > > < | 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 | test_versionable_config(); test_cx_glob_lists(); test_import_blob(); test_date2(); #if FSLPRINTF_ENABLE_JSON test_printf_json(); #endif test_vpath_1(); test_bind_fmt(); if(0) test_simplify_sql(); } }else{ /* placeholder for use while developing tests. */ if(0) test_repo_extract(); if(0) test_gradient(); } { char const * ckoutUuid = NULL; fsl_id_t ckoutRid = 0; fsl_checkout_version_info(f, &ckoutRid, &ckoutUuid); f_out("checkout UUID=%s (RID %"FSL_ID_T_PFMT")\n", |
︙ | ︙ |
Changes to include/fossil-scm/fossil-db.h.
︙ | ︙ | |||
684 685 686 687 688 689 690 | passed as-is to the callback. See fsl_stmt_each_f() for the semantics of the callback. Returns 0 on success. Returns FSL_RC_MISUSE if !stmt or !callback. */ FSL_EXPORT int fsl_stmt_each( fsl_stmt * stmt, fsl_stmt_each_f callback, | | | | 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 | passed as-is to the callback. See fsl_stmt_each_f() for the semantics of the callback. Returns 0 on success. Returns FSL_RC_MISUSE if !stmt or !callback. */ FSL_EXPORT int fsl_stmt_each( fsl_stmt * stmt, fsl_stmt_each_f callback, void * callbackState ); /** Resets the given statement, analog to sqlite3_reset(). Should be called one time between fsl_stmt_step() iterations when running multiple INSERTS, UPDATES, etc. via the same statement. If resetRowCounter is true then the statement's row counter (st->rowCount) is also reset to 0, else it is left unmodified. (Most use cases don't use the row counter.) Returns 0 on success, FSL_RC_MISUSE if !stmt or stmt has not been prepared, FSL_RC_DB if the underlying reset fails (in which case the error state of the stmt->db handle is updated to contain the error information). @see fsl_stmt_db() @see fsl_stmt_reset() */ FSL_EXPORT int fsl_stmt_reset2( fsl_stmt * stmt, bool resetRowCounter ); /** Equivalent to fsl_stmt_reset2(stmt, 0). */ FSL_EXPORT int fsl_stmt_reset( fsl_stmt * stmt ); /** |
︙ | ︙ | |||
841 842 843 844 845 846 847 | the binding makes an copy of the data. Set makeCopy to false ONLY if you KNOW that the bytes will outlive the binding. Returns 0 on success. On error stmt's underlying db's error state is updated, hopefully with a useful error message. */ FSL_EXPORT int fsl_stmt_bind_text( fsl_stmt * stmt, int index, | | | | | | | | | | 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 | the binding makes an copy of the data. Set makeCopy to false ONLY if you KNOW that the bytes will outlive the binding. Returns 0 on success. On error stmt's underlying db's error state is updated, hopefully with a useful error message. */ FSL_EXPORT int fsl_stmt_bind_text( fsl_stmt * stmt, int index, char const * v, fsl_int_t n, bool makeCopy ); /** Equivalent to fsl_stmt_bind_text() but binds to a named parameter. */ FSL_EXPORT int fsl_stmt_bind_text_name( fsl_stmt * stmt, char const * param, char const * v, fsl_int_t n, bool makeCopy ); /** Binds the first n bytes of v as a blob to the given 1-based bound parameter column in the given statement. See fsl_stmt_bind_text() for the semantics of the makeCopy parameter and return value. */ FSL_EXPORT int fsl_stmt_bind_blob( fsl_stmt * stmt, int index, void const * v, fsl_size_t len, bool makeCopy ); /** Equivalent to fsl_stmt_bind_blob() but binds to a named parameter. */ FSL_EXPORT int fsl_stmt_bind_blob_name( fsl_stmt * stmt, char const * param, void const * v, fsl_int_t len, bool makeCopy ); /** Gets an integer value from the given 0-based result set column, assigns *v to that value, and returns 0 on success. Returns FSL_RC_RANGE if index is out of range for stmt. */ |
︙ | ︙ | |||
1309 1310 1311 1312 1313 1314 1315 | add a counter to their callbackState and increment it from the callback. Returns FSL_RC_MISUSE if !db, db is not opened, !callback, !sql. Returns FSL_RC_RANGE if !*sql. */ FSL_EXPORT int fsl_db_each( fsl_db * db, fsl_stmt_each_f callback, | | | | | 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 | add a counter to their callbackState and increment it from the callback. Returns FSL_RC_MISUSE if !db, db is not opened, !callback, !sql. Returns FSL_RC_RANGE if !*sql. */ FSL_EXPORT int fsl_db_each( fsl_db * db, fsl_stmt_each_f callback, void * callbackState, char const * sql, ... ); /** va_list counterpart to fsl_db_each(). */ FSL_EXPORT int fsl_db_eachv( fsl_db * db, fsl_stmt_each_f callback, void * callbackState, char const * sql, va_list args ); /** Returns the given Julian date value formatted as an ISO8601 string (with a fractional seconds part if msPrecision is true, else without it). Returns NULL if !db, db is not connected, j is less than 0, or on allocation error. The returned memory must eventually be freed using fsl_free(). If localTime is true then the value is converted to the local time, otherwise it is not. @see fsl_db_unix_to_iso8601() @see fsl_julian_to_iso8601() @see fsl_iso8601_to_julian() */ FSL_EXPORT char * fsl_db_julian_to_iso8601( fsl_db * db, double j, char msPrecision, char localTime ); /** Returns the given Julian date value formatted as an ISO8601 string (with a fractional seconds part if msPrecision is true, else without it). Returns NULL if !db, db is not connected, j is less than 0, or on allocation error. The returned memory must eventually be freed using fsl_free(). |
︙ | ︙ | |||
1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 | Potential TODO: this is a bit of a wonky interface. Consider changing it to eliminate the role argument, which is only really needed if we have duplicate table names across attached dbs or if we internally mess up and write a table to the wrong db. */ FSL_EXPORT bool fsl_db_table_exists(fsl_db * db, fsl_dbrole_e whichDb, const char *zTable); #if defined(__cplusplus) } /*extern "C"*/ #endif #endif /* NET_FOSSIL_SCM_FSL_DB_H_INCLUDED */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | Potential TODO: this is a bit of a wonky interface. Consider changing it to eliminate the role argument, which is only really needed if we have duplicate table names across attached dbs or if we internally mess up and write a table to the wrong db. */ FSL_EXPORT bool fsl_db_table_exists(fsl_db * db, fsl_dbrole_e whichDb, const char *zTable); /** The elipsis counterpart of fsl_stmt_bind_fmtv(). */ FSL_EXPORT int fsl_stmt_bind_fmt( fsl_stmt * st, char const * fmt, ... ); /** Binds a series of values using a formatting string. The string may contain the following characters, each of which refers to the next argument in the args list: '-': binds a NULL and expects a NULL placeholder in the argument list (for consistency's sake). 'i': binds an int32 'I': binds an int64 'R': binds a fsl_id_t ('R' as in 'RID') 'f': binds a double 's': binds a (char const *) as a string or NULL. 'S': binds a (char const *) as a blob or NULL. 'b': binds a (fsl_buffer const *) as a string or NULL. 'B': binds a (fsl_buffer const *) as a blob or NULL. ' ': spaces are allowed for readability and are ignored. Returns 0 on success, any number of other FSL_RC_xxx codes on error. */ FSL_EXPORT int fsl_stmt_bind_fmtv( fsl_stmt * st, char const * fmt, va_list args ); #if defined(__cplusplus) } /*extern "C"*/ #endif #endif /* NET_FOSSIL_SCM_FSL_DB_H_INCLUDED */ |
Changes to src/db.c.
︙ | ︙ | |||
571 572 573 574 575 576 577 | ? rc : ((FSL_RC_STEP_ERROR==strc) ? FSL_RC_DB : 0); } } | | | 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 | ? rc : ((FSL_RC_STEP_ERROR==strc) ? FSL_RC_DB : 0); } } int fsl_stmt_reset2( fsl_stmt * stmt, bool resetRowCounter ){ if(!stmt || !stmt->stmt || !stmt->db) return FSL_RC_MISUSE; else{ int const rc = sqlite3_reset(stmt->stmt); if(resetRowCounter) stmt->rowCount = 0; assert(stmt->db); return rc ? fsl_err_from_db(stmt->db, rc) |
︙ | ︙ | |||
606 607 608 609 610 611 612 | int fsl_stmt_param_count( fsl_stmt const * stmt ){ return (!stmt || !stmt->stmt) ? -1 : stmt->paramCount; } | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > > < < < | 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | int fsl_stmt_param_count( fsl_stmt const * stmt ){ return (!stmt || !stmt->stmt) ? -1 : stmt->paramCount; } int fsl_stmt_bind_fmtv( fsl_stmt * st, char const * fmt, va_list args ){ int rc = 0, ndx; char const * pos = fmt; if(!fmt || !(st && st->stmt && st->db && st->db->dbh)) return FSL_RC_MISUSE; else if(!*fmt) return FSL_RC_RANGE; for( ndx = 1; !rc && *pos; ++pos, ++ndx ){ if(' '==*pos){ --ndx; continue; } if(ndx > st->paramCount){ rc = fsl_error_set(&st->db->error, FSL_RC_RANGE, "Column index %d is out of bounds.", ndx); break; } switch(*pos){ case '-': va_arg(args,void const *) /* skip arg */; rc = fsl_stmt_bind_null(st, ndx); break; case 'i': rc = fsl_stmt_bind_int32(st, ndx, va_arg(args,int32_t)); break; |
︙ | ︙ | |||
704 705 706 707 708 709 710 711 712 713 714 715 716 717 | rc = fsl_error_set(&st->db->error, FSL_RC_RANGE, "Invalid format character: '%c'", *pos); break; } } return rc; } #define BIND_PARAM_CHECK \ if(!(stmt && stmt->stmt && stmt->db && stmt->db->dbh)) return FSL_RC_MISUSE; else #define BIND_PARAM_CHECK2 BIND_PARAM_CHECK \ if(ndx<1 || ndx>stmt->paramCount) return FSL_RC_RANGE; else int fsl_stmt_bind_null( fsl_stmt * stmt, int ndx ){ BIND_PARAM_CHECK2 { | > > > > > > > > > > > > > | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 | rc = fsl_error_set(&st->db->error, FSL_RC_RANGE, "Invalid format character: '%c'", *pos); break; } } return rc; } /** The elipsis counterpart of fsl_stmt_bind_fmtv(). */ int fsl_stmt_bind_fmt( fsl_stmt * st, char const * fmt, ... ){ int rc; va_list args; va_start(args,fmt); return fsl_stmt_bind_fmtv(st, fmt, args); va_end(args); return rc; } #define BIND_PARAM_CHECK \ if(!(stmt && stmt->stmt && stmt->db && stmt->db->dbh)) return FSL_RC_MISUSE; else #define BIND_PARAM_CHECK2 BIND_PARAM_CHECK \ if(ndx<1 || ndx>stmt->paramCount) return FSL_RC_RANGE; else int fsl_stmt_bind_null( fsl_stmt * stmt, int ndx ){ BIND_PARAM_CHECK2 { |
︙ | ︙ | |||
745 746 747 748 749 750 751 | BIND_PARAM_CHECK2 { int const rc = sqlite3_bind_double( stmt->stmt, ndx, (double)v ); return rc ? fsl_err_from_db(stmt->db, rc) : 0; } } int fsl_stmt_bind_blob( fsl_stmt * stmt, int ndx, void const * src, | | | < | 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 | BIND_PARAM_CHECK2 { int const rc = sqlite3_bind_double( stmt->stmt, ndx, (double)v ); return rc ? fsl_err_from_db(stmt->db, rc) : 0; } } int fsl_stmt_bind_blob( fsl_stmt * stmt, int ndx, void const * src, fsl_size_t len, bool makeCopy ){ BIND_PARAM_CHECK2 { int rc; rc = sqlite3_bind_blob( stmt->stmt, ndx, src, (int)len, makeCopy ? SQLITE_TRANSIENT : SQLITE_STATIC ); return rc ? fsl_err_from_db(stmt->db, rc) : 0; } } int fsl_stmt_bind_text( fsl_stmt * stmt, int ndx, char const * src, fsl_int_t len, bool makeCopy ){ BIND_PARAM_CHECK { int rc; if(len<0) len = fsl_strlen((char const *)src); rc = sqlite3_bind_text( stmt->stmt, ndx, src, len, makeCopy ? SQLITE_TRANSIENT : SQLITE_STATIC ); return rc ? fsl_err_from_db(stmt->db, rc) : 0; } } int fsl_stmt_bind_null_name( fsl_stmt * stmt, char const * param ){ BIND_PARAM_CHECK{ return fsl_stmt_bind_null( stmt, sqlite3_bind_parameter_index( stmt->stmt, param) ); } |
︙ | ︙ | |||
812 813 814 815 816 817 818 | param), v); } } int fsl_stmt_bind_text_name( fsl_stmt * stmt, char const * param, char const * v, fsl_int_t n, | | | | 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 | param), v); } } int fsl_stmt_bind_text_name( fsl_stmt * stmt, char const * param, char const * v, fsl_int_t n, bool makeCopy ){ BIND_PARAM_CHECK { return fsl_stmt_bind_text(stmt, sqlite3_bind_parameter_index( stmt->stmt, param), v, n, makeCopy); } } int fsl_stmt_bind_blob_name( fsl_stmt * stmt, char const * param, void const * v, fsl_int_t len, bool makeCopy ){ BIND_PARAM_CHECK { return fsl_stmt_bind_blob(stmt, sqlite3_bind_parameter_index( stmt->stmt, param), v, len, makeCopy); } } |
︙ | ︙ |