1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-07 02:42:48 +03:00

Add new interfaces to the test_quota.c module: sqlite3_quota_ftruncate(),

sqlite3_quota_file_size(), sqlite3_quota_file_truesize(), and
sqlite3_quota_file_mtime().

FossilOrigin-Name: 2fa9f54309aea9927fb3695a986febd4963df7d1
This commit is contained in:
drh
2012-04-10 17:53:47 +00:00
parent 35c86a94cf
commit c00ce490c5
5 changed files with 309 additions and 28 deletions

View File

@@ -1,5 +1,5 @@
C Fix\sa\scopy/paste\serror\sin\sa\scomment\sin\sthe\sfuzzer.\s\sNo\schanges\sto\scode. C Add\snew\sinterfaces\sto\sthe\stest_quota.c\smodule:\s\ssqlite3_quota_ftruncate(),\nsqlite3_quota_file_size(),\ssqlite3_quota_file_truesize(),\sand\nsqlite3_quota_file_mtime().
D 2012-04-10T16:05:27.567 D 2012-04-10T17:53:47.880
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20 F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -221,8 +221,8 @@ F src/test_mutex.c a6bd7b9cf6e19d989e31392b06ac8d189f0d573e
F src/test_onefile.c 5e1382e7844c703c77c4c2aee82f8359555b5a8e F src/test_onefile.c 5e1382e7844c703c77c4c2aee82f8359555b5a8e
F src/test_osinst.c 7f790ac89c5a585d51b341274d9691c3391e0923 F src/test_osinst.c 7f790ac89c5a585d51b341274d9691c3391e0923
F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00
F src/test_quota.c a545115f837da4ef32f6b5578f147b44cfb13fd7 F src/test_quota.c 2ab468f5817b84f7105f78b77c300649ea5af8d1
F src/test_quota.h 9ffa1d3ad6d0a6a24e8670ea64b909c717ec3358 F src/test_quota.h ee5da2ae7f84d1c8e0e0e2ab33f01d69f10259b5
F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9 F src/test_rtree.c aba603c949766c4193f1068b91c787f57274e0d9
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0 F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f F src/test_server.c 2f99eb2837dfa06a4aacf24af24c6affdf66a84f
@@ -651,7 +651,7 @@ F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 F test/quick.test 1681febc928d686362d50057c642f77a02c62e57
F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26
F test/quota.test c2f778dab4c7fb07bcfa962cc5c762f36d8061dc F test/quota.test c2f778dab4c7fb07bcfa962cc5c762f36d8061dc
F test/quota2.test 7e1c84f71f59388963fa8181a1292c87ae814d2d F test/quota2.test bc9fdb2e46aace691c1a01a9cc8d097bd4d7c1ab
F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6 F test/quote.test 215897dbe8de1a6f701265836d6601cc6ed103e6
F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459 F test/randexpr1.tcl 40dec52119ed3a2b8b2a773bce24b63a3a746459
F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df F test/randexpr1.test eda062a97e60f9c38ae8d806b03b0ddf23d796df
@@ -1000,7 +1000,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
P 09d5581c81fb6a9bf6a369d0abf5ef6b54637576 P 7433f2b5508ebf09d0e3e32a995f1126eaab8999
R 943f4e1c7aaa43ed0d8f52aacf8c1af9 R 85564f41a960bd198f1c0cd3cc4e501c
U drh U drh
Z bb1afab0a69bf02921a229d11d9f81e5 Z b7da54f2c32a033935fc1a3628198083

View File

@@ -1 +1 @@
7433f2b5508ebf09d0e3e32a995f1126eaab8999 2fa9f54309aea9927fb3695a986febd4963df7d1

View File

@@ -120,6 +120,9 @@ struct quota_FILE {
FILE *f; /* Open stdio file pointer */ FILE *f; /* Open stdio file pointer */
sqlite3_int64 iOfst; /* Current offset into the file */ sqlite3_int64 iOfst; /* Current offset into the file */
quotaFile *pFile; /* The file record in the quota system */ quotaFile *pFile; /* The file record in the quota system */
#if SQLITE_OS_WIN
char *zMbcsName; /* Full MBCS pathname of the file */
#endif
}; };
@@ -979,7 +982,7 @@ int sqlite3_quota_file(const char *zFilename){
quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode){ quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode){
quota_FILE *p = 0; quota_FILE *p = 0;
char *zFull = 0; char *zFull = 0;
char *zFullTranslated; char *zFullTranslated = 0;
int rc; int rc;
quotaGroup *pGroup; quotaGroup *pGroup;
quotaFile *pFile; quotaFile *pFile;
@@ -995,7 +998,6 @@ quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode){
zFullTranslated = quota_utf8_to_mbcs(zFull); zFullTranslated = quota_utf8_to_mbcs(zFull);
if( zFullTranslated==0 ) goto quota_fopen_error; if( zFullTranslated==0 ) goto quota_fopen_error;
p->f = fopen(zFullTranslated, zMode); p->f = fopen(zFullTranslated, zMode);
quota_mbcs_free(zFullTranslated);
if( p->f==0 ) goto quota_fopen_error; if( p->f==0 ) goto quota_fopen_error;
quotaEnter(); quotaEnter();
pGroup = quotaGroupFind(zFull); pGroup = quotaGroupFind(zFull);
@@ -1010,9 +1012,13 @@ quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode){
} }
quotaLeave(); quotaLeave();
sqlite3_free(zFull); sqlite3_free(zFull);
#if SQLITE_OS_WIN
p->zMbcsName = zFullTranslated;
#endif
return p; return p;
quota_fopen_error: quota_fopen_error:
quota_mbcs_free(zFullTranslated);
sqlite3_free(zFull); sqlite3_free(zFull);
if( p && p->f ) fclose(p->f); if( p && p->f ) fclose(p->f);
sqlite3_free(p); sqlite3_free(p);
@@ -1045,6 +1051,7 @@ size_t sqlite3_quota_fwrite(
sqlite3_int64 iEnd; sqlite3_int64 iEnd;
sqlite3_int64 szNew; sqlite3_int64 szNew;
quotaFile *pFile; quotaFile *pFile;
size_t rc;
iOfst = ftell(p->f); iOfst = ftell(p->f);
iEnd = iOfst + size*nmemb; iEnd = iOfst + size*nmemb;
@@ -1068,8 +1075,23 @@ size_t sqlite3_quota_fwrite(
pGroup->iSize = szNew; pGroup->iSize = szNew;
pFile->iSize = iEnd; pFile->iSize = iEnd;
quotaLeave(); quotaLeave();
}else{
pFile = 0;
} }
return fwrite(pBuf, size, nmemb, p->f); rc = fwrite(pBuf, size, nmemb, p->f);
/* If the write was incomplete, adjust the file size and group size
** downward */
if( rc<nmemb && pFile ){
size_t nWritten = rc>=0 ? rc : 0;
sqlite3_int64 iNewEnd = iOfst + size*nWritten;
if( iNewEnd<iEnd ) iNewEnd = iEnd;
quotaEnter();
pFile->pGroup->iSize += iNewEnd - pFile->iSize;
pFile->iSize = iNewEnd;
quotaLeave();
}
return rc;
} }
/* /*
@@ -1093,6 +1115,9 @@ int sqlite3_quota_fclose(quota_FILE *p){
} }
quotaLeave(); quotaLeave();
} }
#if SQLITE_OS_WIN
quota_mbcs_free(p->zMbcsName);
#endif
sqlite3_free(p); sqlite3_free(p);
return rc; return rc;
} }
@@ -1135,6 +1160,83 @@ long sqlite3_quota_ftell(quota_FILE *p){
return ftell(p->f); return ftell(p->f);
} }
/*
** Truncate a file to szNew bytes.
*/
int sqlite3_quota_ftruncate(quota_FILE *p, sqlite3_int64 szNew){
quotaFile *pFile = p->pFile;
int rc;
if( (pFile = p->pFile)!=0 && pFile->iSize<szNew ){
quotaGroup *pGroup;
if( pFile->iSize<szNew ){
/* This routine cannot be used to extend a file that is under
** quota management. Only true truncation is allowed. */
return -1;
}
pGroup = pFile->pGroup;
quotaEnter();
pGroup->iSize += szNew - pFile->iSize;
quotaLeave();
}
#if SQLITE_OS_UNIX
rc = ftruncate(fileno(p->f), szNew);
#endif
#if SQLITE_OS_WIN
rc = _chsize_s(_fileno(p->f), szNew);
#endif
if( pFile && rc==0 ){
quotaGroup *pGroup = pFile->pGroup;
quotaEnter();
pGroup->iSize += szNew - pFile->iSize;
pFile->iSize = szNew;
quotaLeave();
}
return rc;
}
/*
** Determine the time that the given file was last modified, in
** seconds size 1970. Write the result into *pTime. Return 0 on
** success and non-zero on any kind of error.
*/
int sqlite3_quota_file_mtime(quota_FILE *p, time_t *pTime){
int rc;
#if SQLITE_OS_UNIX
struct stat buf;
rc = fstat(fileno(p->f), &buf);
#endif
#if SQLITE_OS_WIN
struct _stati64 buf;
rc = _stati64(p->zMbcsName, &buf);
#endif
if( rc==0 ) *pTime = buf.st_mtime;
return rc;
}
/*
** Return the true size of the file, as reported by the operating
** system.
*/
sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE *p){
int rc;
#if SQLITE_OS_UNIX
struct stat buf;
rc = fstat(fileno(p->f), &buf);
#endif
#if SQLITE_OS_WIN
struct _stati64 buf;
rc = _stati64(p->zMbcsName, &buf);
#endif
return rc==0 ? buf.st_size : -1;
}
/*
** Return the size of the file, as it is known to the quota subsystem.
*/
sqlite3_int64 sqlite3_quota_file_size(quota_FILE *p){
return p->pFile ? p->pFile->iSize : -1;
}
/* /*
** Remove a managed file. Update quotas accordingly. ** Remove a managed file. Update quotas accordingly.
*/ */
@@ -1656,6 +1758,96 @@ static int test_quota_ftell(
return TCL_OK; return TCL_OK;
} }
/*
** tclcmd: sqlite3_quota_ftruncate HANDLE SIZE
*/
static int test_quota_ftruncate(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
quota_FILE *p;
sqlite3_int64 x;
Tcl_WideInt w;
int rc;
if( objc!=3 ){
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE SIZE");
return TCL_ERROR;
}
p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
if( Tcl_GetWideIntFromObj(interp, objv[2], &w) ) return TCL_ERROR;
x = (sqlite3_int64)w;
rc = sqlite3_quota_ftruncate(p, x);
Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
return TCL_OK;
}
/*
** tclcmd: sqlite3_quota_file_size HANDLE
*/
static int test_quota_file_size(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
quota_FILE *p;
sqlite3_int64 x;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
return TCL_ERROR;
}
p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
x = sqlite3_quota_file_size(p);
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
return TCL_OK;
}
/*
** tclcmd: sqlite3_quota_file_truesize HANDLE
*/
static int test_quota_file_truesize(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
quota_FILE *p;
sqlite3_int64 x;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
return TCL_ERROR;
}
p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
x = sqlite3_quota_file_truesize(p);
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
return TCL_OK;
}
/*
** tclcmd: sqlite3_quota_file_mtime HANDLE
*/
static int test_quota_file_mtime(
void * clientData,
Tcl_Interp *interp,
int objc,
Tcl_Obj *CONST objv[]
){
quota_FILE *p;
time_t t;
if( objc!=2 ){
Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
return TCL_ERROR;
}
p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
t = 0;
sqlite3_quota_file_mtime(p, &t);
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(t));
return TCL_OK;
}
/* /*
** tclcmd: sqlite3_quota_remove FILENAME ** tclcmd: sqlite3_quota_remove FILENAME
*/ */
@@ -1713,21 +1905,25 @@ int Sqlitequota_Init(Tcl_Interp *interp){
char *zName; char *zName;
Tcl_ObjCmdProc *xProc; Tcl_ObjCmdProc *xProc;
} aCmd[] = { } aCmd[] = {
{ "sqlite3_quota_initialize", test_quota_initialize }, { "sqlite3_quota_initialize", test_quota_initialize },
{ "sqlite3_quota_shutdown", test_quota_shutdown }, { "sqlite3_quota_shutdown", test_quota_shutdown },
{ "sqlite3_quota_set", test_quota_set }, { "sqlite3_quota_set", test_quota_set },
{ "sqlite3_quota_file", test_quota_file }, { "sqlite3_quota_file", test_quota_file },
{ "sqlite3_quota_dump", test_quota_dump }, { "sqlite3_quota_dump", test_quota_dump },
{ "sqlite3_quota_fopen", test_quota_fopen }, { "sqlite3_quota_fopen", test_quota_fopen },
{ "sqlite3_quota_fread", test_quota_fread }, { "sqlite3_quota_fread", test_quota_fread },
{ "sqlite3_quota_fwrite", test_quota_fwrite }, { "sqlite3_quota_fwrite", test_quota_fwrite },
{ "sqlite3_quota_fclose", test_quota_fclose }, { "sqlite3_quota_fclose", test_quota_fclose },
{ "sqlite3_quota_fflush", test_quota_fflush }, { "sqlite3_quota_fflush", test_quota_fflush },
{ "sqlite3_quota_fseek", test_quota_fseek }, { "sqlite3_quota_fseek", test_quota_fseek },
{ "sqlite3_quota_rewind", test_quota_rewind }, { "sqlite3_quota_rewind", test_quota_rewind },
{ "sqlite3_quota_ftell", test_quota_ftell }, { "sqlite3_quota_ftell", test_quota_ftell },
{ "sqlite3_quota_remove", test_quota_remove }, { "sqlite3_quota_ftruncate", test_quota_ftruncate },
{ "sqlite3_quota_glob", test_quota_glob }, { "sqlite3_quota_file_size", test_quota_file_size },
{ "sqlite3_quota_file_truesize", test_quota_file_truesize },
{ "sqlite3_quota_file_mtime", test_quota_file_mtime },
{ "sqlite3_quota_remove", test_quota_remove },
{ "sqlite3_quota_glob", test_quota_glob },
}; };
int i; int i;

View File

@@ -29,6 +29,14 @@
#ifndef _QUOTA_H_ #ifndef _QUOTA_H_
#include "sqlite3.h" #include "sqlite3.h"
#include <stdio.h> #include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#if SQLITE_OS_UNIX
# include <unistd.h>
#endif
#if SQLITE_OS_WIN
# include <windows.h>
#endif
/* Make this callable from C++ */ /* Make this callable from C++ */
#ifdef __cplusplus #ifdef __cplusplus
@@ -182,6 +190,48 @@ int sqlite3_quota_fseek(quota_FILE*, long, int);
void sqlite3_quota_rewind(quota_FILE*); void sqlite3_quota_rewind(quota_FILE*);
long sqlite3_quota_ftell(quota_FILE*); long sqlite3_quota_ftell(quota_FILE*);
/*
** Truncate a file previously opened by sqlite3_quota_fopen(). Return
** zero on success and non-zero on any kind of failure.
**
** The newSize argument must be less than or equal to the current file size.
** Any attempt to "truncate" a file to a larger size results in
** undefined behavior.
*/
int sqlite3_quota_ftrunate(quota_FILE*, sqlite3_int64 newSize);
/*
** Return the last modification time of the opened file, in seconds
** since 1970.
*/
int sqlite3_quota_file_mtime(quota_FILE*, time_t *pTime);
/*
** Return the size of the file as it is known to the quota system.
**
** This size might be different from the true size of the file on
** disk if some outside process has modified the file without using the
** quota mechanism, or if calls to sqlite3_quota_fwrite() have occurred
** which have increased the file size, but those writes have not yet been
** forced to disk using sqlite3_quota_fflush().
**
** Return -1 if the file is not participating in quota management.
*/
sqlite3_int64 sqlite3_quota_file_size(quota_FILE*);
/*
** Return the true size of the file.
**
** The true size should be the same as the size of the file as known
** to the quota system, however the sizes might be different if the
** file has been extended or truncated via some outside process or if
** pending writes have not yet been flushed to disk.
**
** Return -1 if the file does not exist or if the size of the file
** cannot be determined for some reason.
*/
sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE*);
/* /*
** Delete a file from the disk, if that file is under quota management. ** Delete a file from the disk, if that file is under quota management.
** Adjust quotas accordingly. ** Adjust quotas accordingly.

View File

@@ -76,6 +76,13 @@ do_test quota2-1.1 {
do_test quota2-1.2 { do_test quota2-1.2 {
set ::quota set ::quota
} {PWD/quota2a/xyz.txt 4000 7000} } {PWD/quota2a/xyz.txt 4000 7000}
do_test quota2-1.2.1 {
sqlite3_quota_file_size $::h1
} {4000}
do_test quota2-1.2.2 {
sqlite3_quota_fflush $::h1 1
sqlite3_quota_file_truesize $::h1
} {4000}
do_test quota2-1.3 { do_test quota2-1.3 {
sqlite3_quota_rewind $::h1 sqlite3_quota_rewind $::h1
set ::x [sqlite3_quota_fread $::h1 1001 7] set ::x [sqlite3_quota_fread $::h1 1001 7]
@@ -112,15 +119,43 @@ do_test quota2-1.11 {
standard_path [sqlite3_quota_dump] standard_path [sqlite3_quota_dump]
} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 1 0}}} } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 1 0}}}
do_test quota2-1.12 { do_test quota2-1.12 {
sqlite3_quota_ftruncate $::h1 3500
sqlite3_quota_file_size $::h1
} {3500}
do_test quota2-1.13 {
sqlite3_quota_file_truesize $::h1
} {3500}
do_test quota2-1.14 {
standard_path [sqlite3_quota_dump]
} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 3500 {PWD/quota2a/xyz.txt 3500 1 0}}}
do_test quota2-1.15 {
sqlite3_quota_fseek $::h1 0 SEEK_END
sqlite3_quota_ftell $::h1
} {3500}
do_test quota2-1.16 {
sqlite3_quota_fwrite $::h1 1 7000 $bigtext
} {500}
do_test quota2-1.17 {
sqlite3_quota_ftell $::h1
} {4000}
do_test quota2-1.18 {
sqlite3_quota_file_size $::h1
} {4000}
do_test quota2-1.19 {
sqlite3_quota_fflush $::h1 1
sqlite3_quota_file_truesize $::h1
} {4000}
do_test quota2-1.20 {
sqlite3_quota_fclose $::h1 sqlite3_quota_fclose $::h1
standard_path [sqlite3_quota_dump] standard_path [sqlite3_quota_dump]
} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 0 0}}} } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 0 0}}}
do_test quota2-1.13 { do_test quota2-1.21 {
sqlite3_quota_remove quota2a/xyz.txt sqlite3_quota_remove quota2a/xyz.txt
standard_path [sqlite3_quota_dump] standard_path [sqlite3_quota_dump]
} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}} } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}
set quota {} set quota {}
do_test quota2-2.1 { do_test quota2-2.1 {
set ::h1 [sqlite3_quota_fopen quota2c/xyz.txt w+b] set ::h1 [sqlite3_quota_fopen quota2c/xyz.txt w+b]