public FuncDef(short nArg, byte iPrefEnc, FUNC iflags, object pUserData, FuncDef pNext, dxFunc xFunc, dxStep xStep, dxFinal xFinalize, string zName, FuncDef pHash, FuncDestructor pDestructor) { this.nArg = nArg; this.iPrefEnc = iPrefEnc; this.flags = iflags; this.pUserData = pUserData; this.pNext = pNext; this.xFunc = xFunc; this.xStep = xStep; this.xFinalize = xFinalize; this.zName = zName; this.pHash = pHash; this.pDestructor = pDestructor; }
static int sqlite3_create_function_v2( sqlite3 db, string zFunc, int nArg, int enc, object p, dxFunc xFunc, //)(sqlite3_context*,int,sqlite3_value *), dxStep xStep,//)(sqlite3_context*,int,sqlite3_value *), dxFinal xFinal,//)(sqlite3_context) dxFDestroy xDestroy//)(void ) ) { int rc = SQLITE_ERROR; FuncDestructor pArg = null; sqlite3_mutex_enter( db.mutex ); if ( xDestroy != null ) { pArg = new FuncDestructor();//(FuncDestructor )sqlite3DbMallocZero(db, sizeof(FuncDestructor)); //if( null==pArg ){ // xDestroy(p); // goto out; //} pArg.xDestroy = xDestroy; pArg.pUserData = p; } rc = sqlite3CreateFunc( db, zFunc, nArg, (byte)enc, p, xFunc, xStep, xFinal, pArg ); if ( pArg != null && pArg.nRef == 0 ) { Debug.Assert( rc != SQLITE_OK ); //xDestroy(p); sqlite3DbFree( db, ref pArg ); } //_out: rc = sqlite3ApiExit( db, rc ); sqlite3_mutex_leave( db.mutex ); return rc; }
/* ** This function is exactly the same as sqlite3_create_function(), except ** that it is designed to be called by internal code. The difference is ** that if a malloc() fails in sqlite3_create_function(), an error code ** is returned and the mallocFailed flag cleared. */ static int sqlite3CreateFunc( sqlite3 db, string zFunctionName, int nArg, u8 enc, object pUserData, dxFunc xFunc, //)(sqlite3_context*,int,sqlite3_value *), dxStep xStep,//)(sqlite3_context*,int,sqlite3_value *), dxFinal xFinal, //)(sqlite3_context), FuncDestructor pDestructor ) { FuncDef p; int nName; Debug.Assert( sqlite3_mutex_held( db.mutex ) ); if ( zFunctionName == null || ( xFunc != null && ( xFinal != null || xStep != null ) ) || ( xFunc == null && ( xFinal != null && xStep == null ) ) || ( xFunc == null && ( xFinal == null && xStep != null ) ) || ( nArg < -1 || nArg > SQLITE_MAX_FUNCTION_ARG ) || ( 255 < ( nName = sqlite3Strlen30( zFunctionName ) ) ) ) { return SQLITE_MISUSE_BKPT(); } #if !SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the ** SQLITE_UTF16NATIVE macro. SQLITE_UTF16 is not used internally. ** ** If SQLITE_ANY is specified, add three versions of the function ** to the hash table. */ if( enc==SQLITE_UTF16 ){ enc = SQLITE_UTF16NATIVE; }else if( enc==SQLITE_ANY ){ int rc; rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8, pUserData, xFunc, xStep, xFinal, pDestructor); if( rc==SQLITE_OK ){ rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE, pUserData, xFunc, xStep, xFinal, pDestructor); } if( rc!=SQLITE_OK ){ return rc; } enc = SQLITE_UTF16BE; } #else enc = SQLITE_UTF8; #endif /* Check if an existing function is being overridden or deleted. If so, ** and there are active VMs, then return SQLITE_BUSY. If a function ** is being overridden/deleted but there are no active VMs, allow the ** operation to continue but invalidate all precompiled statements. */ p = sqlite3FindFunction( db, zFunctionName, nName, nArg, enc, 0 ); if ( p != null && p.iPrefEnc == enc && p.nArg == nArg ) { if ( db.activeVdbeCnt != 0 ) { sqlite3Error( db, SQLITE_BUSY, "unable to delete/modify user-function due to active statements" ); //Debug.Assert( 0 == db.mallocFailed ); return SQLITE_BUSY; } else { sqlite3ExpirePreparedStatements( db ); } } p = sqlite3FindFunction( db, zFunctionName, nName, nArg, enc, 1 ); Debug.Assert( p != null /*|| db.mallocFailed != 0 */ ); //if ( p == null ) //{ // return SQLITE_NOMEM; //} /* If an older version of the function with a configured destructor is ** being replaced invoke the destructor function here. */ functionDestroy( db, p ); if ( pDestructor != null ) { pDestructor.nRef++; } p.pDestructor = pDestructor; p.flags = 0; p.xFunc = xFunc; p.xStep = xStep; p.xFinalize = xFinal; p.pUserData = pUserData; p.nArg = (i16)nArg; return SQLITE_OK; }