Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Call quota callback destructors from within sqlite3_quota_shutdown(). |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
fb80c6f3de73ed832faaeb8c4d83e135 |
User & Date: | dan 2010-09-01 16:19:57.000 |
Context
2010-09-01
| ||
18:00 | Add tests to quota.test. (check-in: ec9af6ebd4 user: dan tags: trunk) | |
16:19 | Call quota callback destructors from within sqlite3_quota_shutdown(). (check-in: fb80c6f3de user: dan tags: trunk) | |
15:26 | Boundary value fix to the descriptive comment at the top of test_quota.c. (check-in: 7f6072f082 user: drh tags: trunk) | |
Changes
Changes to src/test_quota.c.
︙ | ︙ | |||
152 153 154 155 156 157 158 159 | /* If the reference count and threshold for a quotaGroup are both ** zero, then destroy the quotaGroup. */ static void quotaGroupDeref(quotaGroup *pGroup){ if( pGroup->pFiles==0 && pGroup->iLimit==0 ){ if( pGroup->pNext ) pGroup->pNext->ppPrev = pGroup->ppPrev; | > < | 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | /* If the reference count and threshold for a quotaGroup are both ** zero, then destroy the quotaGroup. */ static void quotaGroupDeref(quotaGroup *pGroup){ if( pGroup->pFiles==0 && pGroup->iLimit==0 ){ *pGroup->ppPrev = pGroup->pNext; if( pGroup->pNext ) pGroup->pNext->ppPrev = pGroup->ppPrev; if( pGroup->xDestroy ) pGroup->xDestroy(pGroup->pArg); sqlite3_free(pGroup); } } /* ** Return TRUE if string z matches glob pattern zGlob. |
︙ | ︙ | |||
611 612 613 614 615 616 617 | if( gQuota.isInitialized==0 ) return SQLITE_MISUSE; for(pGroup=gQuota.pGroup; pGroup; pGroup=pGroup->pNext){ if( pGroup->pFiles ) return SQLITE_MISUSE; } while( gQuota.pGroup ){ pGroup = gQuota.pGroup; gQuota.pGroup = pGroup->pNext; | > | | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 | if( gQuota.isInitialized==0 ) return SQLITE_MISUSE; for(pGroup=gQuota.pGroup; pGroup; pGroup=pGroup->pNext){ if( pGroup->pFiles ) return SQLITE_MISUSE; } while( gQuota.pGroup ){ pGroup = gQuota.pGroup; gQuota.pGroup = pGroup->pNext; pGroup->iLimit = 0; quotaGroupDeref(pGroup); } gQuota.isInitialized = 0; sqlite3_mutex_free(gQuota.pMutex); sqlite3_vfs_unregister(&gQuota.sThisVfs); memset(&gQuota, 0, sizeof(gQuota)); return SQLITE_OK; } |
︙ | ︙ | |||
755 756 757 758 759 760 761 | /* ** Destructor for a TCL quota-over-limit callback. */ static void tclCallbackDestructor(void *pObj){ TclQuotaCallback *p = (TclQuotaCallback*)pObj; if( p ){ Tcl_DecrRefCount(p->pScript); | | | 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 | /* ** Destructor for a TCL quota-over-limit callback. */ static void tclCallbackDestructor(void *pObj){ TclQuotaCallback *p = (TclQuotaCallback*)pObj; if( p ){ Tcl_DecrRefCount(p->pScript); sqlite3_free((char *)p); } } /* ** tclcmd: sqlite3_quota_initialize NAME MAKEDEFAULT */ static int test_quota_initialize( |
︙ | ︙ | |||
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 | ){ const char *zPattern; /* File pattern to configure */ sqlite3_int64 iLimit; /* Initial quota in bytes */ Tcl_Obj *pScript; /* Tcl script to invoke to increase quota */ int rc; /* Value returned by quota_set() */ TclQuotaCallback *p; /* Callback object */ int nScript; /* Length of callback script */ /* Process arguments */ if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "PATTERN LIMIT SCRIPT"); return TCL_ERROR; } zPattern = Tcl_GetString(objv[1]); if( Tcl_GetWideIntFromObj(interp, objv[2], &iLimit) ) return TCL_ERROR; pScript = objv[3]; Tcl_GetStringFromObj(pScript, &nScript); if( nScript>0 ){ /* Allocate a TclQuotaCallback object */ | > | > > > > > > > | < | 827 828 829 830 831 832 833 834 835 836 837 838 839 840 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 | ){ const char *zPattern; /* File pattern to configure */ sqlite3_int64 iLimit; /* Initial quota in bytes */ Tcl_Obj *pScript; /* Tcl script to invoke to increase quota */ int rc; /* Value returned by quota_set() */ TclQuotaCallback *p; /* Callback object */ int nScript; /* Length of callback script */ void (*xDestroy)(void*); /* Optional destructor for pArg */ /* Process arguments */ if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "PATTERN LIMIT SCRIPT"); return TCL_ERROR; } zPattern = Tcl_GetString(objv[1]); if( Tcl_GetWideIntFromObj(interp, objv[2], &iLimit) ) return TCL_ERROR; pScript = objv[3]; Tcl_GetStringFromObj(pScript, &nScript); if( nScript>0 ){ /* Allocate a TclQuotaCallback object */ p = (TclQuotaCallback *)sqlite3_malloc(sizeof(TclQuotaCallback)); if( !p ){ Tcl_SetResult(interp, (char *)"SQLITE_NOMEM", TCL_STATIC); return TCL_OK; } memset(p, 0, sizeof(TclQuotaCallback)); p->interp = interp; Tcl_IncrRefCount(pScript); p->pScript = pScript; xDestroy = tclCallbackDestructor; }else{ p = 0; xDestroy = 0; } /* Invoke sqlite3_quota_set() */ rc = sqlite3_quota_set(zPattern, iLimit, tclQuotaCallback, (void*)p,xDestroy); Tcl_SetResult(interp, (char *)sqlite3TestErrorName(rc), TCL_STATIC); return TCL_OK; } /* ** tclcmd: sqlite3_quota_dump |
︙ | ︙ |
Changes to test/quota.test.
︙ | ︙ | |||
117 118 119 120 121 122 123 | } do_test quota-3.1.1 { file delete -force test.db sqlite3_quota_initialize "" 1 sqlite3_quota_set *test.db 4096 quota_check } {SQLITE_OK} | < > > > > | > > | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | } do_test quota-3.1.1 { file delete -force test.db sqlite3_quota_initialize "" 1 sqlite3_quota_set *test.db 4096 quota_check } {SQLITE_OK} do_test quota-3.1.2 { sqlite3 db test.db execsql { PRAGMA page_size = 1024; PRAGMA journal_mode = delete; PRAGMA auto_vacuum = off; CREATE TABLE t1(a PRIMARY KEY, b); INSERT INTO t1 VALUES(1, 'one'); } file size test.db } {3072} do_test quota-3.1.3 { sqlite3 db2 test.db set ::quota [list] execsql { CREATE TABLE t2(a, b) } db2 set ::quota } {} do_test quota-3.1.4 { catchsql { CREATE TABLE t3(a, b) } } {1 {database or disk is full}} do_test quota-3.1.5 { set ::quota_request_ok 1 execsql { CREATE TABLE t3(a, b) } } {} do_test quota-3.X { catch { db close } catch { db2 close } } {0} #------------------------------------------------------------------------- # Quotas are deleted when unused and when there limit is set to zero # # Return a list of all currently defined quotas. Each quota is identified # by its pattern. proc quota_list {} { set allq {} foreach q [sqlite3_quota_dump] { lappend allq [lindex $q 0] } return [lsort $allq] } do_test quota-4.1.1 { sqlite3_quota_set *test.db 0 {} quota_list } {} do_test quota-4.1.2 { sqlite3_quota_set *test.db 4096 {} quota_list } {*test.db} do_test quota-4.1.3 { sqlite3_quota_set *test2.db 0 {} quota_list } {*test.db} do_test quota-4.1.4 { sqlite3_quota_set *test2.db 100000 {} quota_list } {*test.db *test2.db} do_test quota-4.1.5 { sqlite3_quota_set *test.db 0 {} quota_list } {*test2.db} do_test quota-4.1.6 { file delete -force test2.db test2.db-journal test2.db-wal sqlite3 db test2.db db eval {CREATE TABLE t2(x); INSERT INTO t2 VALUES('tab-t2');} quota_list } {*test2.db} do_test quota-4.1.7 { catchsql {INSERT INTO t2 VALUES(zeroblob(200000))} } {1 {database or disk is full}} do_test quota-4.1.8 { sqlite3 db2 test2.db db2 eval {SELECT * FROM t2} } {tab-t2} do_test quota-4.1.9 { sqlite3_quota_set *test2.db 0 {} catchsql {INSERT INTO t2 VALUES(zeroblob(200000))} } {0 {}} do_test quota-4.1.10 { quota_list } {*test2.db} do_test quota-4.1.11 { db2 close quota_list } {*test2.db} do_test quota-4.1.12 { db close quota_list } {} do_test quota-4.2.1 { sqlite3_quota_set A 1000 {} sqlite3_quota_set B 1000 {} sqlite3_quota_set C 1000 {} sqlite3_quota_set D 1000 {} quota_list } {A B C D} do_test quota-4.2.2 { sqlite3_quota_set C 0 {} sqlite3_quota_set B 0 {} quota_list } {A D} do_test quota-4.2.3 { sqlite3_quota_set A 0 {} sqlite3_quota_set D 0 {} quota_list } {} do_test quota-4.2.4 { sqlite3_quota_set A 1000 {} sqlite3_quota_set B 1000 {} sqlite3_quota_set C 1000 {} sqlite3_quota_set A 0 {} sqlite3_quota_set B 0 {} sqlite3_quota_set C 0 {} quota_list } {} do_test quota-4.2.5 { sqlite3_quota_set A 1000 {} sqlite3_quota_set B 1000 {} sqlite3_quota_set C 1000 {} sqlite3_quota_set C 0 {} sqlite3_quota_set B 0 {} sqlite3_quota_set A 0 {} quota_list } {} do_test quota-4.3.1 { sqlite3_quota_set A 1000 quota_callback sqlite3 db A sqlite3_quota_set A 0 quota_callback db close quota_list } {} do_test quota-4.4.1 { sqlite3_quota_set A 1000 quota_callback sqlite3_quota_shutdown } {SQLITE_OK} do_test quota-4.4.2 { quota_list } {} catch { sqlite3_quota_shutdown } finish_test |