/ Check-in [61669c95]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add sqlite3_quota_ferror() and sqlite3_quota_file_available() interfaces to test_quota.c. Change sqlite3_quota_fwrite() to use a const input buffer.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 61669c95859e187618fb2fb4249306a947ae8d26
User & Date: drh 2012-06-05 13:56:15
Context
2012-06-06
19:01
Avoid resetting the shared-cache schema when on of the connections using the shared cache closes. Delay resetting the schema until the last connection closes. check-in: 635e3a76 user: drh tags: trunk
2012-06-05
19:20
Merge the latest trunk changes into shared-schema branch. Also fix a C99-ism in that branch. check-in: 42338e9e user: drh tags: shared-schema
13:56
Add sqlite3_quota_ferror() and sqlite3_quota_file_available() interfaces to test_quota.c. Change sqlite3_quota_fwrite() to use a const input buffer. check-in: 61669c95 user: drh tags: trunk
2012-05-31
13:10
Avoid calling fchown() if the process is not running as root. check-in: 70c419a4 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test_quota.c.

  1038   1038   }
  1039   1039   
  1040   1040   /*
  1041   1041   ** Write content into a quota_FILE.  Invoke the quota callback and block
  1042   1042   ** the write if we exceed quota.
  1043   1043   */
  1044   1044   size_t sqlite3_quota_fwrite(
  1045         -  void *pBuf,            /* Take content to write from here */
         1045  +  const void *pBuf,      /* Take content to write from here */
  1046   1046     size_t size,           /* Size of each element */
  1047   1047     size_t nmemb,          /* Number of elements */
  1048   1048     quota_FILE *p          /* Write to this quota_FILE objecct */
  1049   1049   ){
  1050   1050     sqlite3_int64 iOfst;
  1051   1051     sqlite3_int64 iEnd;
  1052   1052     sqlite3_int64 szNew;
  1053   1053     quotaFile *pFile;
  1054   1054     size_t rc;
  1055         -  
         1055  +
  1056   1056     iOfst = ftell(p->f);
  1057   1057     iEnd = iOfst + size*nmemb;
  1058   1058     pFile = p->pFile;
  1059   1059     if( pFile && pFile->iSize<iEnd ){
  1060   1060       quotaGroup *pGroup = pFile->pGroup;
  1061   1061       quotaEnter();
  1062   1062       szNew = pGroup->iSize - pFile->iSize + iEnd;
................................................................................
  1087   1087       sqlite3_int64 iNewEnd = iOfst + size*nWritten;
  1088   1088       if( iNewEnd<iEnd ) iNewEnd = iEnd;
  1089   1089       quotaEnter();
  1090   1090       pFile->pGroup->iSize += iNewEnd - pFile->iSize;
  1091   1091       pFile->iSize = iNewEnd;
  1092   1092       quotaLeave();
  1093   1093     }
  1094         -  return rc;    
         1094  +  return rc;
  1095   1095   }
  1096   1096   
  1097   1097   /*
  1098   1098   ** Close an open quota_FILE stream.
  1099   1099   */
  1100   1100   int sqlite3_quota_fclose(quota_FILE *p){
  1101   1101     int rc;
................................................................................
  1155   1155   
  1156   1156   /*
  1157   1157   ** Tell the current location of a quota_FILE stream.
  1158   1158   */
  1159   1159   long sqlite3_quota_ftell(quota_FILE *p){
  1160   1160     return ftell(p->f);
  1161   1161   }
         1162  +
         1163  +/*
         1164  +** Test the error indicator for the given file.
         1165  +*/
         1166  +int sqlite3_quota_ferror(quota_FILE *p){
         1167  +  return ferror(p->f);
         1168  +}
  1162   1169   
  1163   1170   /*
  1164   1171   ** Truncate a file to szNew bytes.
  1165   1172   */
  1166   1173   int sqlite3_quota_ftruncate(quota_FILE *p, sqlite3_int64 szNew){
  1167   1174     quotaFile *pFile = p->pFile;
  1168   1175     int rc;
................................................................................
  1232   1239   
  1233   1240   /*
  1234   1241   ** Return the size of the file, as it is known to the quota subsystem.
  1235   1242   */
  1236   1243   sqlite3_int64 sqlite3_quota_file_size(quota_FILE *p){
  1237   1244     return p->pFile ? p->pFile->iSize : -1;
  1238   1245   }
         1246  + 
         1247  +/*
         1248  +** Determine the amount of data in bytes available for reading
         1249  +** in the given file.
         1250  +*/
         1251  +long sqlite3_quota_file_available(quota_FILE *p){
         1252  +  FILE* f = p->f;
         1253  +  long pos1, pos2;
         1254  +  int rc;
         1255  +  pos1 = ftell(f);
         1256  +  if ( pos1 < 0 ) return -1;
         1257  +  rc = fseek(f, 0, SEEK_END);
         1258  +  if ( rc != 0 ) return -1;
         1259  +  pos2 = ftell(f);
         1260  +  if ( pos2 < 0 ) return -1;
         1261  +  rc = fseek(f, pos1, SEEK_SET);
         1262  +  if ( rc != 0 ) return -1;
         1263  +  return pos2 - pos1;
         1264  +}
  1239   1265   
  1240   1266   /*
  1241   1267   ** Remove a managed file.  Update quotas accordingly.
  1242   1268   */
  1243   1269   int sqlite3_quota_remove(const char *zFilename){
  1244   1270     char *zFull;            /* Full pathname for zFilename */
  1245   1271     size_t nFull;           /* Number of bytes in zFilename */
................................................................................
  1890   1916     }
  1891   1917     zPattern = Tcl_GetString(objv[1]);
  1892   1918     zText = Tcl_GetString(objv[2]);
  1893   1919     rc = quotaStrglob(zPattern, zText);
  1894   1920     Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  1895   1921     return TCL_OK;
  1896   1922   }
         1923  +
         1924  +/*
         1925  +** tclcmd: sqlite3_quota_file_available HANDLE
         1926  +**
         1927  +** Return the number of bytes from the current file point to the end of
         1928  +** the file.
         1929  +*/
         1930  +static int test_quota_file_available(
         1931  +  void * clientData,
         1932  +  Tcl_Interp *interp,
         1933  +  int objc,
         1934  +  Tcl_Obj *CONST objv[]
         1935  +){
         1936  +  quota_FILE *p;
         1937  +  sqlite3_int64 x;
         1938  +  if( objc!=2 ){
         1939  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
         1940  +    return TCL_ERROR;
         1941  +  }
         1942  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1943  +  x = sqlite3_quota_file_available(p);
         1944  +  Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
         1945  +  return TCL_OK;
         1946  +}
         1947  +
         1948  +/*
         1949  +** tclcmd: sqlite3_quota_ferror HANDLE
         1950  +**
         1951  +** Return true if the file handle is in the error state.
         1952  +*/
         1953  +static int test_quota_ferror(
         1954  +  void * clientData,
         1955  +  Tcl_Interp *interp,
         1956  +  int objc,
         1957  +  Tcl_Obj *CONST objv[]
         1958  +){
         1959  +  quota_FILE *p;
         1960  +  int x;
         1961  +  if( objc!=2 ){
         1962  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
         1963  +    return TCL_ERROR;
         1964  +  }
         1965  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1966  +  x = sqlite3_quota_ferror(p);
         1967  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(x));
         1968  +  return TCL_OK;
         1969  +}
  1897   1970   
  1898   1971   /*
  1899   1972   ** This routine registers the custom TCL commands defined in this
  1900   1973   ** module.  This should be the only procedure visible from outside
  1901   1974   ** of this module.
  1902   1975   */
  1903   1976   int Sqlitequota_Init(Tcl_Interp *interp){
................................................................................
  1920   1993       { "sqlite3_quota_ftell",         test_quota_ftell },
  1921   1994       { "sqlite3_quota_ftruncate",     test_quota_ftruncate },
  1922   1995       { "sqlite3_quota_file_size",     test_quota_file_size },
  1923   1996       { "sqlite3_quota_file_truesize", test_quota_file_truesize },
  1924   1997       { "sqlite3_quota_file_mtime",    test_quota_file_mtime },
  1925   1998       { "sqlite3_quota_remove",        test_quota_remove },
  1926   1999       { "sqlite3_quota_glob",          test_quota_glob },
         2000  +    { "sqlite3_quota_file_available",test_quota_file_available },
         2001  +    { "sqlite3_quota_ferror",        test_quota_ferror },
  1927   2002     };
  1928   2003     int i;
  1929   2004   
  1930   2005     for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
  1931   2006       Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  1932   2007     }
  1933   2008   
  1934   2009     return TCL_OK;
  1935   2010   }
  1936   2011   #endif

Changes to src/test_quota.h.

   158    158   
   159    159   /*
   160    160   ** Perform I/O against a quota_FILE object.  When doing writes, the
   161    161   ** quota mechanism may result in a short write, in order to prevent
   162    162   ** the sum of sizes of all files from going over quota.
   163    163   */
   164    164   size_t sqlite3_quota_fread(void*, size_t, size_t, quota_FILE*);
   165         -size_t sqlite3_quota_fwrite(void*, size_t, size_t, quota_FILE*);
          165  +size_t sqlite3_quota_fwrite(const void*, size_t, size_t, quota_FILE*);
   166    166   
   167    167   /*
   168    168   ** Flush all written content held in memory buffers out to disk.
   169    169   ** This is the equivalent of fflush() in the standard library.
   170    170   **
   171    171   ** If the hardSync parameter is true (non-zero) then this routine
   172    172   ** also forces OS buffers to disk - the equivalent of fsync().
................................................................................
   186    186   ** Move the read/write pointer for a quota_FILE object.  Or tell the
   187    187   ** current location of the read/write pointer.
   188    188   */
   189    189   int sqlite3_quota_fseek(quota_FILE*, long, int);
   190    190   void sqlite3_quota_rewind(quota_FILE*);
   191    191   long sqlite3_quota_ftell(quota_FILE*);
   192    192   
          193  +/*
          194  +** Test the error indicator for the given file.
          195  +**
          196  +** Return non-zero if the error indicator is set.
          197  +*/
          198  +int sqlite3_quota_ferror(quota_FILE*);
          199  +
   193    200   /*
   194    201   ** Truncate a file previously opened by sqlite3_quota_fopen().  Return
   195    202   ** zero on success and non-zero on any kind of failure.
   196    203   **
   197    204   ** The newSize argument must be less than or equal to the current file size.
   198    205   ** Any attempt to "truncate" a file to a larger size results in 
   199    206   ** undefined behavior.
   200    207   */
   201         -int sqlite3_quota_ftrunate(quota_FILE*, sqlite3_int64 newSize);
          208  +int sqlite3_quota_ftruncate(quota_FILE*, sqlite3_int64 newSize);
   202    209   
   203    210   /*
   204    211   ** Return the last modification time of the opened file, in seconds
   205    212   ** since 1970.
   206    213   */
   207    214   int sqlite3_quota_file_mtime(quota_FILE*, time_t *pTime);
   208    215   
................................................................................
   228    235   ** pending writes have not yet been flushed to disk.
   229    236   **
   230    237   ** Return -1 if the file does not exist or if the size of the file
   231    238   ** cannot be determined for some reason.
   232    239   */
   233    240   sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE*);
   234    241   
          242  +/*
          243  +** Determine the amount of data in bytes available for reading
          244  +** in the given file.
          245  +**
          246  +** Return -1 if the amount cannot be determined for some reason.
          247  +*/
          248  +long sqlite3_quota_file_available(quota_FILE*);
          249  +
   235    250   /*
   236    251   ** Delete a file from the disk, if that file is under quota management.
   237    252   ** Adjust quotas accordingly.
   238    253   **
   239    254   ** If zFilename is the name of a directory that matches one of the
   240    255   ** quota glob patterns, then all files under quota management that
   241    256   ** are contained within that directory are deleted.

Changes to test/quota2.test.

   160    160   do_test quota2-2.1 {
   161    161     set ::h1 [sqlite3_quota_fopen quota2c/xyz.txt w+b]
   162    162     sqlite3_quota_fwrite $::h1 1 7000 $bigtext
   163    163   } {7000}
   164    164   do_test quota2-2.2 {
   165    165     set ::quota
   166    166   } {}
   167         -do_test quota2-2.3 {
          167  +do_test quota2-2.3.1 {
   168    168     sqlite3_quota_rewind $::h1
          169  +  sqlite3_quota_file_available $::h1
          170  +} {7000}
          171  +do_test quota2-2.3.2 {
   169    172     set ::x [sqlite3_quota_fread $::h1 1001 7]
   170    173     string length $::x
   171    174   } {6006}
          175  +do_test quota2-2.3.3 {
          176  +  sqlite3_quota_file_available $::h1
          177  +} {0}
   172    178   do_test quota2-2.4 {
   173    179     string match $::x [string range $::bigtext 0 6005]
   174    180   } {1}
   175    181   do_test quota2-2.5 {
   176    182     sqlite3_quota_fseek $::h1 0 SEEK_END
   177    183     sqlite3_quota_ftell $::h1
   178    184   } {7000}
   179    185   do_test quota2-2.6 {
   180    186     sqlite3_quota_fseek $::h1 -100 SEEK_END
   181    187     sqlite3_quota_ftell $::h1
   182    188   } {6900}
          189  +do_test quota2-2.6.1 {
          190  +  sqlite3_quota_file_available $::h1
          191  +} {100}
   183    192   do_test quota2-2.7 {
   184    193     sqlite3_quota_fseek $::h1 -100 SEEK_CUR
   185    194     sqlite3_quota_ftell $::h1
   186    195   } {6800}
          196  +do_test quota2-2.7.1 {
          197  +  sqlite3_quota_file_available $::h1
          198  +} {200}
   187    199   do_test quota2-2.8 {
   188    200     sqlite3_quota_fseek $::h1 50 SEEK_CUR
   189    201     sqlite3_quota_ftell $::h1
   190    202   } {6850}
          203  +do_test quota2-2.8.1 {
          204  +  sqlite3_quota_file_available $::h1
          205  +} {150}
   191    206   do_test quota2-2.9 {
   192    207     sqlite3_quota_fseek $::h1 50 SEEK_SET
   193    208     sqlite3_quota_ftell $::h1
   194    209   } {50}
          210  +do_test quota2-2.9.1 {
          211  +  sqlite3_quota_file_available $::h1
          212  +} {6950}
   195    213   do_test quota2-2.10 {
   196    214     sqlite3_quota_rewind $::h1
   197    215     sqlite3_quota_ftell $::h1
   198    216   } {0}
          217  +do_test quota2-2.10.1 {
          218  +  sqlite3_quota_file_available $::h1
          219  +} {7000}
          220  +do_test quota2-2.10.2 {
          221  +  sqlite3_quota_ferror $::h1
          222  +} {0}
   199    223   do_test quota2-2.11 {
   200    224     standard_path [sqlite3_quota_dump]
   201    225   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}
   202    226   do_test quota2-2.12 {
   203    227     sqlite3_quota_fclose $::h1
   204    228     standard_path [sqlite3_quota_dump]
   205    229   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}