Skip to content

Commit

Permalink
impr: fileio - add offset and limit (nalgeon#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
phrrngtn authored Feb 22, 2023
1 parent 07549eb commit db539b0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
4 changes: 3 additions & 1 deletion docs/fileio.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ Main features:
- Create a symlink.
- List files in a directory.

### fileio_read(path)
### fileio_read(path [,offset [,limit]])

Reads the file specified by `path` and returns its contents as `blob`.
If offset is supplied and is non-zero and less than the file size, then seek to that offset before reading.
If limit is supplied and is non-zero then limit the number of bytes read to limit.

```sql
select fileio_write('hello.txt', 'hello world');
Expand Down
50 changes: 44 additions & 6 deletions src/fileio/legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ SQLITE_EXTENSION_INIT3
** Throw an SQLITE_IOERR if there are difficulties pulling the file
** off of disk.
*/
static void readFileContents(sqlite3_context* ctx, const char* zName) {
static void readFileContents(sqlite3_context* ctx, const char* zName, const int nOffset, const int nLimit) {
FILE* in;
sqlite3_int64 nIn;
void* pBuf;
Expand All @@ -98,6 +98,23 @@ static void readFileContents(sqlite3_context* ctx, const char* zName) {
fseek(in, 0, SEEK_END);
nIn = ftell(in);
rewind(in);
if (nOffset > nIn) { /* offset is greater than the size of the file */
sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
fclose(in);
return;
}
if (nLimit <0){
sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
fclose(in);
return;
}
if (nOffset > 0) {
fseek(in, nOffset, SEEK_SET);
nIn -= nOffset;
}
if (nLimit>0 && nLimit < nIn){
nIn=nLimit;
}
db = sqlite3_context_db_handle(ctx);
mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
if (nIn > mxBlob) {
Expand Down Expand Up @@ -127,11 +144,32 @@ static void readFileContents(sqlite3_context* ctx, const char* zName) {
*/
static void sqlite3_readfile(sqlite3_context* context, int argc, sqlite3_value** argv) {
const char* zName;
(void)(argc); /* Unused parameter */
int nOffset;
int nLimit;
zName = (const char*)sqlite3_value_text(argv[0]);
if (zName == 0)
return;
readFileContents(context, zName);
nOffset=0;
nLimit=0;

if (argc>=2 && sqlite3_value_type(argv[1])!=SQLITE_NULL) {
nOffset=sqlite3_value_int(argv[1]);
if (nOffset<0) {
sqlite3_result_error(context, "offset must be >= 0", -1);
return;
}
}

if (argc==3 && sqlite3_value_type(argv[2])!=SQLITE_NULL) {
nLimit=sqlite3_value_int(argv[2]);
if (nLimit<0) {
sqlite3_result_error(context, "limit must be >= 0", -1);
return;
}
}


readFileContents(context, zName, nOffset, nLimit);
}

/*
Expand Down Expand Up @@ -967,8 +1005,8 @@ int fileio_scalar_init(sqlite3* db) {
sqlite3_create_function(db, "fileio_mkdir", -1, flags, 0, sqlite3_mkdir, 0, 0);
sqlite3_create_function(db, "mkdir", -1, flags, 0, sqlite3_mkdir, 0, 0);

sqlite3_create_function(db, "fileio_read", 1, flags, 0, sqlite3_readfile, 0, 0);
sqlite3_create_function(db, "readfile", 1, flags, 0, sqlite3_readfile, 0, 0);
sqlite3_create_function(db, "fileio_read", -1, flags, 0, sqlite3_readfile, 0, 0);
sqlite3_create_function(db, "readfile", -1, flags, 0, sqlite3_readfile, 0, 0);

sqlite3_create_function(db, "fileio_symlink", 2, flags, 0, sqlite3_symlink, 0, 0);
sqlite3_create_function(db, "symlink", 2, flags, 0, sqlite3_symlink, 0, 0);
Expand Down Expand Up @@ -1153,4 +1191,4 @@ INT closedir(LPDIR dirp) {
sqlite3_free(dirp);
return result;
}
#endif
#endif

0 comments on commit db539b0

Please sign in to comment.