xref: /sqlite-3.40.0/ext/misc/fileio.c (revision 47ebd4ca)
1 /*
2 ** 2014-06-13
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 SQLite extension implements SQL functions readfile() and
14 ** writefile().
15 */
16 #include "sqlite3ext.h"
17 SQLITE_EXTENSION_INIT1
18 #include <stdio.h>
19 
20 /*
21 ** Implementation of the "readfile(X)" SQL function.  The entire content
22 ** of the file named X is read and returned as a BLOB.  NULL is returned
23 ** if the file does not exist or is unreadable.
24 */
25 static void readfileFunc(
26   sqlite3_context *context,
27   int argc,
28   sqlite3_value **argv
29 ){
30   const char *zName;
31   FILE *in;
32   long nIn;
33   void *pBuf;
34 
35   (void)(argc);  /* Unused parameter */
36   zName = (const char*)sqlite3_value_text(argv[0]);
37   if( zName==0 ) return;
38   in = fopen(zName, "rb");
39   if( in==0 ) return;
40   fseek(in, 0, SEEK_END);
41   nIn = ftell(in);
42   rewind(in);
43   pBuf = sqlite3_malloc( nIn );
44   if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
45     sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
46   }else{
47     sqlite3_free(pBuf);
48   }
49   fclose(in);
50 }
51 
52 /*
53 ** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
54 ** is written into file X.  The number of bytes written is returned.  Or
55 ** NULL is returned if something goes wrong, such as being unable to open
56 ** file X for writing.
57 */
58 static void writefileFunc(
59   sqlite3_context *context,
60   int argc,
61   sqlite3_value **argv
62 ){
63   FILE *out;
64   const char *z;
65   sqlite3_int64 rc;
66   const char *zFile;
67 
68   (void)(argc);  /* Unused parameter */
69   zFile = (const char*)sqlite3_value_text(argv[0]);
70   if( zFile==0 ) return;
71   out = fopen(zFile, "wb");
72   if( out==0 ) return;
73   z = (const char*)sqlite3_value_blob(argv[1]);
74   if( z==0 ){
75     rc = 0;
76   }else{
77     rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
78   }
79   fclose(out);
80   sqlite3_result_int64(context, rc);
81 }
82 
83 
84 #ifdef _WIN32
85 __declspec(dllexport)
86 #endif
87 int sqlite3_fileio_init(
88   sqlite3 *db,
89   char **pzErrMsg,
90   const sqlite3_api_routines *pApi
91 ){
92   int rc = SQLITE_OK;
93   SQLITE_EXTENSION_INIT2(pApi);
94   (void)pzErrMsg;  /* Unused parameter */
95   rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
96                                readfileFunc, 0, 0);
97   if( rc==SQLITE_OK ){
98     rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
99                                  writefileFunc, 0, 0);
100   }
101   return rc;
102 }
103