drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 1 | /* |
| 2 | ** 2011 December 1 |
| 3 | ** |
| 4 | ** The author disclaims copyright to this source code. In place of |
| 5 | ** a legal notice, here is a blessing: |
| 6 | ** |
| 7 | ** May you do good and not evil. |
| 8 | ** May you find forgiveness for yourself and forgive others. |
| 9 | ** May you share freely, never taking more than you give. |
| 10 | ** |
| 11 | ************************************************************************* |
| 12 | ** |
| 13 | ** This file contains the interface definition for the quota a VFS shim. |
| 14 | ** |
| 15 | ** This particular shim enforces a quota system on files. One or more |
| 16 | ** database files are in a "quota group" that is defined by a GLOB |
| 17 | ** pattern. A quota is set for the combined size of all files in the |
| 18 | ** the group. A quota of zero means "no limit". If the total size |
| 19 | ** of all files in the quota group is greater than the limit, then |
| 20 | ** write requests that attempt to enlarge a file fail with SQLITE_FULL. |
| 21 | ** |
| 22 | ** However, before returning SQLITE_FULL, the write requests invoke |
| 23 | ** a callback function that is configurable for each quota group. |
| 24 | ** This callback has the opportunity to enlarge the quota. If the |
| 25 | ** callback does enlarge the quota such that the total size of all |
| 26 | ** files within the group is less than the new quota, then the write |
| 27 | ** continues as if nothing had happened. |
| 28 | */ |
| 29 | #ifndef _QUOTA_H_ |
| 30 | #include "sqlite3.h" |
| 31 | #include <stdio.h> |
drh | c00ce49 | 2012-04-10 17:53:47 | [diff] [blame] | 32 | #include <sys/types.h> |
| 33 | #include <sys/stat.h> |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 34 | |
drh | 663cebf | 2011-12-12 19:47:25 | [diff] [blame] | 35 | /* Make this callable from C++ */ |
| 36 | #ifdef __cplusplus |
| 37 | extern "C" { |
| 38 | #endif |
| 39 | |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 40 | /* |
| 41 | ** Initialize the quota VFS shim. Use the VFS named zOrigVfsName |
| 42 | ** as the VFS that does the actual work. Use the default if |
| 43 | ** zOrigVfsName==NULL. |
| 44 | ** |
| 45 | ** The quota VFS shim is named "quota". It will become the default |
| 46 | ** VFS if makeDefault is non-zero. |
| 47 | ** |
| 48 | ** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once |
| 49 | ** during start-up. |
| 50 | */ |
| 51 | int sqlite3_quota_initialize(const char *zOrigVfsName, int makeDefault); |
| 52 | |
| 53 | /* |
| 54 | ** Shutdown the quota system. |
| 55 | ** |
| 56 | ** All SQLite database connections must be closed before calling this |
| 57 | ** routine. |
| 58 | ** |
| 59 | ** THIS ROUTINE IS NOT THREADSAFE. Call this routine exactly once while |
| 60 | ** shutting down in order to free all remaining quota groups. |
| 61 | */ |
| 62 | int sqlite3_quota_shutdown(void); |
| 63 | |
| 64 | /* |
| 65 | ** Create or destroy a quota group. |
| 66 | ** |
| 67 | ** The quota group is defined by the zPattern. When calling this routine |
| 68 | ** with a zPattern for a quota group that already exists, this routine |
| 69 | ** merely updates the iLimit, xCallback, and pArg values for that quota |
| 70 | ** group. If zPattern is new, then a new quota group is created. |
| 71 | ** |
| 72 | ** The zPattern is always compared against the full pathname of the file. |
| 73 | ** Even if APIs are called with relative pathnames, SQLite converts the |
| 74 | ** name to a full pathname before comparing it against zPattern. zPattern |
drh | eff1433 | 2011-12-02 15:27:41 | [diff] [blame] | 75 | ** is a glob pattern with the following matching rules: |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 76 | ** |
| 77 | ** '*' Matches any sequence of zero or more characters. |
| 78 | ** |
| 79 | ** '?' Matches exactly one character. |
| 80 | ** |
| 81 | ** [...] Matches one character from the enclosed list of |
drh | eff1433 | 2011-12-02 15:27:41 | [diff] [blame] | 82 | ** characters. "]" can be part of the list if it is |
| 83 | ** the first character. Within the list "X-Y" matches |
| 84 | ** characters X or Y or any character in between the |
| 85 | ** two. Ex: "[0-9]" matches any digit. |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 86 | ** |
| 87 | ** [^...] Matches one character not in the enclosed list. |
| 88 | ** |
drh | eff1433 | 2011-12-02 15:27:41 | [diff] [blame] | 89 | ** / Matches either / or \. This allows glob patterns |
| 90 | ** containing / to work on both unix and windows. |
| 91 | ** |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 92 | ** Note that, unlike unix shell globbing, the directory separator "/" |
| 93 | ** can match a wildcard. So, for example, the pattern "/abc/xyz/" "*" |
| 94 | ** matches any files anywhere in the directory hierarchy beneath |
drh | eff1433 | 2011-12-02 15:27:41 | [diff] [blame] | 95 | ** /abc/xyz. |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 96 | ** |
drh | a003691 | 2011-12-02 15:31:07 | [diff] [blame] | 97 | ** The glob algorithm works on bytes. Multi-byte UTF8 characters are |
| 98 | ** matched as if each byte were a separate character. |
| 99 | ** |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 100 | ** If the iLimit for a quota group is set to zero, then the quota group |
| 101 | ** is disabled and will be deleted when the last database connection using |
| 102 | ** the quota group is closed. |
| 103 | ** |
| 104 | ** Calling this routine on a zPattern that does not exist and with a |
| 105 | ** zero iLimit is a no-op. |
| 106 | ** |
| 107 | ** A quota group must exist with a non-zero iLimit prior to opening |
| 108 | ** database connections if those connections are to participate in the |
| 109 | ** quota group. Creating a quota group does not affect database connections |
| 110 | ** that are already open. |
drh | 69b2232 | 2011-12-03 00:13:06 | [diff] [blame] | 111 | ** |
| 112 | ** The patterns that define the various quota groups should be distinct. |
| 113 | ** If the same filename matches more than one quota group pattern, then |
| 114 | ** the behavior of this package is undefined. |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 115 | */ |
| 116 | int sqlite3_quota_set( |
| 117 | const char *zPattern, /* The filename pattern */ |
| 118 | sqlite3_int64 iLimit, /* New quota to set for this quota group */ |
| 119 | void (*xCallback)( /* Callback invoked when going over quota */ |
| 120 | const char *zFilename, /* Name of file whose size increases */ |
| 121 | sqlite3_int64 *piLimit, /* IN/OUT: The current limit */ |
| 122 | sqlite3_int64 iSize, /* Total size of all files in the group */ |
| 123 | void *pArg /* Client data */ |
| 124 | ), |
| 125 | void *pArg, /* client data passed thru to callback */ |
| 126 | void (*xDestroy)(void*) /* Optional destructor for pArg */ |
| 127 | ); |
| 128 | |
| 129 | /* |
drh | 69b2232 | 2011-12-03 00:13:06 | [diff] [blame] | 130 | ** Bring the named file under quota management, assuming its name matches |
| 131 | ** the glob pattern of some quota group. Or if it is already under |
| 132 | ** management, update its size. If zFilename does not match the glob |
| 133 | ** pattern of any quota group, this routine is a no-op. |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 134 | */ |
| 135 | int sqlite3_quota_file(const char *zFilename); |
| 136 | |
| 137 | /* |
| 138 | ** The following object serves the same role as FILE in the standard C |
| 139 | ** library. It represents an open connection to a file on disk for I/O. |
drh | 69b2232 | 2011-12-03 00:13:06 | [diff] [blame] | 140 | ** |
| 141 | ** A single quota_FILE should not be used by two or more threads at the |
| 142 | ** same time. Multiple threads can be using different quota_FILE objects |
| 143 | ** simultaneously, but not the same quota_FILE object. |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 144 | */ |
| 145 | typedef struct quota_FILE quota_FILE; |
| 146 | |
| 147 | /* |
| 148 | ** Create a new quota_FILE object used to read and/or write to the |
| 149 | ** file zFilename. The zMode parameter is as with standard library zMode. |
| 150 | */ |
| 151 | quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode); |
| 152 | |
| 153 | /* |
| 154 | ** Perform I/O against a quota_FILE object. When doing writes, the |
| 155 | ** quota mechanism may result in a short write, in order to prevent |
| 156 | ** the sum of sizes of all files from going over quota. |
| 157 | */ |
| 158 | size_t sqlite3_quota_fread(void*, size_t, size_t, quota_FILE*); |
drh | 98c78ea | 2012-06-05 13:56:15 | [diff] [blame] | 159 | size_t sqlite3_quota_fwrite(const void*, size_t, size_t, quota_FILE*); |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 160 | |
| 161 | /* |
drh | 69b2232 | 2011-12-03 00:13:06 | [diff] [blame] | 162 | ** Flush all written content held in memory buffers out to disk. |
drh | 27cec37 | 2011-12-13 23:26:10 | [diff] [blame] | 163 | ** This is the equivalent of fflush() in the standard library. |
| 164 | ** |
| 165 | ** If the hardSync parameter is true (non-zero) then this routine |
| 166 | ** also forces OS buffers to disk - the equivalent of fsync(). |
| 167 | ** |
| 168 | ** This routine return zero on success and non-zero if something goes |
| 169 | ** wrong. |
drh | 69b2232 | 2011-12-03 00:13:06 | [diff] [blame] | 170 | */ |
drh | 27cec37 | 2011-12-13 23:26:10 | [diff] [blame] | 171 | int sqlite3_quota_fflush(quota_FILE*, int hardSync); |
drh | 69b2232 | 2011-12-03 00:13:06 | [diff] [blame] | 172 | |
| 173 | /* |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 174 | ** Close a quota_FILE object and free all associated resources. The |
| 175 | ** file remains under quota management. |
| 176 | */ |
| 177 | int sqlite3_quota_fclose(quota_FILE*); |
| 178 | |
| 179 | /* |
| 180 | ** Move the read/write pointer for a quota_FILE object. Or tell the |
| 181 | ** current location of the read/write pointer. |
| 182 | */ |
| 183 | int sqlite3_quota_fseek(quota_FILE*, long, int); |
| 184 | void sqlite3_quota_rewind(quota_FILE*); |
| 185 | long sqlite3_quota_ftell(quota_FILE*); |
| 186 | |
| 187 | /* |
drh | 98c78ea | 2012-06-05 13:56:15 | [diff] [blame] | 188 | ** Test the error indicator for the given file. |
| 189 | ** |
| 190 | ** Return non-zero if the error indicator is set. |
| 191 | */ |
| 192 | int sqlite3_quota_ferror(quota_FILE*); |
| 193 | |
| 194 | /* |
drh | c00ce49 | 2012-04-10 17:53:47 | [diff] [blame] | 195 | ** Truncate a file previously opened by sqlite3_quota_fopen(). Return |
| 196 | ** zero on success and non-zero on any kind of failure. |
| 197 | ** |
| 198 | ** The newSize argument must be less than or equal to the current file size. |
| 199 | ** Any attempt to "truncate" a file to a larger size results in |
| 200 | ** undefined behavior. |
| 201 | */ |
drh | 98c78ea | 2012-06-05 13:56:15 | [diff] [blame] | 202 | int sqlite3_quota_ftruncate(quota_FILE*, sqlite3_int64 newSize); |
drh | c00ce49 | 2012-04-10 17:53:47 | [diff] [blame] | 203 | |
| 204 | /* |
| 205 | ** Return the last modification time of the opened file, in seconds |
| 206 | ** since 1970. |
| 207 | */ |
| 208 | int sqlite3_quota_file_mtime(quota_FILE*, time_t *pTime); |
| 209 | |
| 210 | /* |
| 211 | ** Return the size of the file as it is known to the quota system. |
| 212 | ** |
| 213 | ** This size might be different from the true size of the file on |
| 214 | ** disk if some outside process has modified the file without using the |
| 215 | ** quota mechanism, or if calls to sqlite3_quota_fwrite() have occurred |
| 216 | ** which have increased the file size, but those writes have not yet been |
| 217 | ** forced to disk using sqlite3_quota_fflush(). |
| 218 | ** |
| 219 | ** Return -1 if the file is not participating in quota management. |
| 220 | */ |
| 221 | sqlite3_int64 sqlite3_quota_file_size(quota_FILE*); |
| 222 | |
| 223 | /* |
| 224 | ** Return the true size of the file. |
| 225 | ** |
| 226 | ** The true size should be the same as the size of the file as known |
| 227 | ** to the quota system, however the sizes might be different if the |
| 228 | ** file has been extended or truncated via some outside process or if |
| 229 | ** pending writes have not yet been flushed to disk. |
| 230 | ** |
| 231 | ** Return -1 if the file does not exist or if the size of the file |
| 232 | ** cannot be determined for some reason. |
| 233 | */ |
| 234 | sqlite3_int64 sqlite3_quota_file_truesize(quota_FILE*); |
| 235 | |
| 236 | /* |
drh | 98c78ea | 2012-06-05 13:56:15 | [diff] [blame] | 237 | ** Determine the amount of data in bytes available for reading |
| 238 | ** in the given file. |
| 239 | ** |
| 240 | ** Return -1 if the amount cannot be determined for some reason. |
| 241 | */ |
| 242 | long sqlite3_quota_file_available(quota_FILE*); |
| 243 | |
| 244 | /* |
drh | 69b2232 | 2011-12-03 00:13:06 | [diff] [blame] | 245 | ** Delete a file from the disk, if that file is under quota management. |
| 246 | ** Adjust quotas accordingly. |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 247 | ** |
drh | 69b2232 | 2011-12-03 00:13:06 | [diff] [blame] | 248 | ** If zFilename is the name of a directory that matches one of the |
| 249 | ** quota glob patterns, then all files under quota management that |
| 250 | ** are contained within that directory are deleted. |
| 251 | ** |
| 252 | ** A standard SQLite result code is returned (SQLITE_OK, SQLITE_NOMEM, etc.) |
| 253 | ** When deleting a directory of files, if the deletion of any one |
| 254 | ** file fails (for example due to an I/O error), then this routine |
| 255 | ** returns immediately, with the error code, and does not try to |
| 256 | ** delete any of the other files in the specified directory. |
| 257 | ** |
| 258 | ** All files are removed from quota management and deleted from disk. |
| 259 | ** However, no attempt is made to remove empty directories. |
| 260 | ** |
| 261 | ** This routine is a no-op for files that are not under quota management. |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 262 | */ |
| 263 | int sqlite3_quota_remove(const char *zFilename); |
| 264 | |
drh | 663cebf | 2011-12-12 19:47:25 | [diff] [blame] | 265 | #ifdef __cplusplus |
| 266 | } /* end of the 'extern "C"' block */ |
| 267 | #endif |
drh | 60f21e4 | 2011-12-01 18:44:21 | [diff] [blame] | 268 | #endif /* _QUOTA_H_ */ |