SQLite第八課 auth.c授權文件解析
代碼剖析
該文件包含了實現sliqte3_set_authorizer函數的代碼。對於SQLite庫來說,該功能
是可選的。嵌入式系統不需要該功能,可以通過預編譯宏-DSQLITE_OMIT_AUTHORIZATION=1
來禁用該選項。實際上在VS的預編譯選項中,添加SQLITE_OMIT_AUTHORIZATION即可!!
如果定義了SQLITE_OMIT_AUTHORIZATION宏,就會忽略該文件的所有代碼
如下介紹兩個重量級的函數:
int sqlite3_set_authorizer
(
sqlite3 *db,
int(*xAuth)(void*,int,const char*,const char*,const char*,const char*),
void *pArg
)
設置或者清空訪問授權函數
sqlite3_set_authorizer函數會將註冊進來的授權函數的指針,傳遞給
數據庫的句柄結構體sqlite3*db,並且也將該函數的第三個參數保存到句柄當中
千萬不要想當然,句柄就是一個指針,可以指向一個結構體的指針。
實際上在這裏有一個值得考慮的問題:如何防止死鎖,一個鎖她的最大範圍
如何控制,在什麽地方才需要真正的加鎖!!
學習如何使用C語言,實現面向對象的編程思想,如何組織函數的處理結構
第三和第四個參數分別是當前正在訪問的表名和列名,認證函數只能返回SQLITE_OK,SQLITE_DENY
SQLITE_IGNORE.如果返回SQLITE_OK,表示允許執行訪問操作。
行,sqlite3_exec函數將返回一個錯誤信息,SQLITE_IGNORE意味著SQL語句將被解析,但是嘗試讀
取,將返回空集合,嘗試寫將被忽略!!
/*
該函數被SQLite調用去執行註冊進來的授權函數
根據給定的參數執行一個認證檢測。返回值可以是SQLITE_OK或者SQLITE_IGNORE或者
SQLITE_DENY,如果返回SQLITE_DENY,pParse會攜帶修改的錯誤信息返回。
*/
int sqlite3AuthCheck(
Parse *pParse,
int code,
const char *zArg1,
const char *zArg2,
const char *zArg3
){
sqlite3 *db = pParse->db;
int rc;
/* Don‘t do any authorization checks if the database is initialising
** or if the parser is being invoked from within sqlite3_declare_vtab.
*/
if( db->init.busy || IN_DECLARE_VTAB ){
return SQLITE_OK;
}
if( db->xAuth==0 ){
return SQLITE_OK;
}
rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
#ifdef SQLITE_USER_AUTHENTICATION
,db->auth.zAuthUser
#endif
);
if( rc==SQLITE_DENY ){
sqlite3ErrorMsg(pParse, "not authorized");
pParse->rc = SQLITE_AUTH;
}else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){
rc = SQLITE_DENY;
sqliteAuthBadReturnCode(pParse);
}
return rc;
}
如下的函數並沒有知道調用的過程:
/*如下的函數例程,並不知道在什麽地方被調用,並且不清楚認證信息是
如何通過函數進行傳遞的,從哪裏來,並且到哪裏去
*/
/*
認證信息進棧。該例程被調用後,認證回調函數的zArg3參數被賦值為zContext,
直到她被彈出。如果pParse為空,該例程取消操作返回。
*/
void sqlite3AuthContextPush
/*
彈出之前通過sqlite3AuthContextPush函數進棧的認證信息
*/
void sqlite3AuthContextPop(AuthContext *pContext)
SQLite第八課 auth.c授權文件解析