101 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
| ** 2014-06-13
 | |
| **
 | |
| ** The author disclaims copyright to this source code.  In place of
 | |
| ** a legal notice, here is a blessing:
 | |
| **
 | |
| **    May you do good and not evil.
 | |
| **    May you find forgiveness for yourself and forgive others.
 | |
| **    May you share freely, never taking more than you give.
 | |
| **
 | |
| ******************************************************************************
 | |
| **
 | |
| ** This SQLite extension implements SQL functions readfile() and
 | |
| ** writefile().
 | |
| */
 | |
| #include "sqlite3ext.h"
 | |
| SQLITE_EXTENSION_INIT1
 | |
| #include <stdio.h>
 | |
| 
 | |
| /*
 | |
| ** Implementation of the "readfile(X)" SQL function.  The entire content
 | |
| ** of the file named X is read and returned as a BLOB.  NULL is returned
 | |
| ** if the file does not exist or is unreadable.
 | |
| */
 | |
| static void readfileFunc(
 | |
|   sqlite3_context *context,
 | |
|   int argc,
 | |
|   sqlite3_value **argv
 | |
| ){
 | |
|   const char *zName;
 | |
|   FILE *in;
 | |
|   long nIn;
 | |
|   void *pBuf;
 | |
| 
 | |
|   zName = (const char*)sqlite3_value_text(argv[0]);
 | |
|   if( zName==0 ) return;
 | |
|   in = fopen(zName, "rb");
 | |
|   if( in==0 ) return;
 | |
|   fseek(in, 0, SEEK_END);
 | |
|   nIn = ftell(in);
 | |
|   rewind(in);
 | |
|   pBuf = sqlite3_malloc( nIn );
 | |
|   if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
 | |
|     sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
 | |
|   }else{
 | |
|     sqlite3_free(pBuf);
 | |
|   }
 | |
|   fclose(in);
 | |
| }
 | |
| 
 | |
| /*
 | |
| ** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
 | |
| ** is written into file X.  The number of bytes written is returned.  Or
 | |
| ** NULL is returned if something goes wrong, such as being unable to open
 | |
| ** file X for writing.
 | |
| */
 | |
| static void writefileFunc(
 | |
|   sqlite3_context *context,
 | |
|   int argc,
 | |
|   sqlite3_value **argv
 | |
| ){
 | |
|   FILE *out;
 | |
|   const char *z;
 | |
|   sqlite3_int64 rc;
 | |
|   const char *zFile;
 | |
| 
 | |
|   zFile = (const char*)sqlite3_value_text(argv[0]);
 | |
|   if( zFile==0 ) return;
 | |
|   out = fopen(zFile, "wb");
 | |
|   if( out==0 ) return;
 | |
|   z = (const char*)sqlite3_value_blob(argv[1]);
 | |
|   if( z==0 ){
 | |
|     rc = 0;
 | |
|   }else{
 | |
|     rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
 | |
|   }
 | |
|   fclose(out);
 | |
|   sqlite3_result_int64(context, rc);
 | |
| }
 | |
| 
 | |
| 
 | |
| #ifdef _WIN32
 | |
| __declspec(dllexport)
 | |
| #endif
 | |
| int sqlite3_fileio_init(
 | |
|   sqlite3 *db, 
 | |
|   char **pzErrMsg, 
 | |
|   const sqlite3_api_routines *pApi
 | |
| ){
 | |
|   int rc = SQLITE_OK;
 | |
|   SQLITE_EXTENSION_INIT2(pApi);
 | |
|   (void)pzErrMsg;  /* Unused parameter */
 | |
|   rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
 | |
|                                readfileFunc, 0, 0);
 | |
|   if( rc==SQLITE_OK ){
 | |
|     rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
 | |
|                                  writefileFunc, 0, 0);
 | |
|   }
 | |
|   return rc;
 | |
| }
 | 
