SQLiteC/C++接口详细介绍之sqlite3类(十五)

2024-03-17 08:20

本文主要是介绍SQLiteC/C++接口详细介绍之sqlite3类(十五),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 返回目录:SQLite—免费开源数据库系列文章目录 

上一篇:SQLiteC/C++接口详细介绍之sqlite3类(十四)

下一篇:SQLiteC/C++接口详细介绍之sqlite3类(十六)

 47.sqlite3_set_authorizer

用法:在SQLite的访问控制中注册一个授权回调函数,用于限制或禁止某些SQL语句的执行。

函数原型如下:

int sqlite3_set_authorizer(sqlite3*,int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),void* pUserData
);

- 第一个参数是数据库连接的指针
- 第二个参数是一个回调函数指针,该回调函数是访问授权的核心,用于审批或拒绝SQL语句的执行
- 第三个参数是用户带的指针,该指针可以在回调函数中使用

回调函数的原型如下:

int my_authorizer_callback(void* pArg, int eCode, const char* zDb, const char* zPtr1, const char* zPtr2, const char* zPtr3);

- 第一个参数是user-data指针
- 第二个参数是一个SQLITE_AUTH_*常量,指示某个SQL语句属于何种类型操作,比如是SELECT、INSERT等等。
- 后面的参数zDb,zPtr1,zPtr2,zPtr3指向与用户访问有关的数据库、表、列或者索引的名称。这四个参数不一定全部被用到,取决于具体的SQL语句类型。

返回值如下:

- 如果回调函数返回SQLITE_DENY,则表示不允许执行这条SQL语句。
- 如果回调函数返回SQLITE_IGNORE,则表示通过SQL语句的执行,但是不允许修改具体的数据库数据。
- 如果回调函数返回SQLITE_OK,则表示允许执行这条SQL语句。

下面是一个简单的示例,回调函数阻止DROP TABLE、DROP VIEW和DELETE语句的执行:

#include <sqlite3.h>
#include <stdio.h>
int authorizer_callback(void* pArg, int eCode, const char* zDb, const char* zPtr1, const char* zPtr2, const char* zPtr3) {if (eCode == SQLITE_DROP_TABLE || eCode == SQLITE_DROP_VIEW || eCode == SQLITE_DELETE) {printf("Unauthorized Operation\n");return SQLITE_DENY;}return SQLITE_OK;
}
int main() {sqlite3 *db;sqlite3_open(":memory:", &db);sqlite3_set_authorizer(db, authorizer_callback, NULL);sqlite3_exec(db, "CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)", NULL, NULL, NULL);sqlite3_exec(db, "INSERT INTO test VALUES (1, 'hello')", NULL, NULL, NULL);sqlite3_exec(db, "DELETE FROM test WHERE id = 1", NULL, NULL, NULL);sqlite3_exec(db, "DROP TABLE test", NULL, NULL, NULL);sqlite3_close(db);return 0;
}

当执行DROP TABLE、DROP VIEW和DELETE语句时,回调函数将阻止执行,并输出"Unauthorized Operation"。需要注意的是,要在执行SQL语句之前设置授权回调函数,否则将无法生效。

48.sqlite3_set_clientdata

sqlite3_set_clientdata函数用于在SQLite的会话中为客户端数据设置指针,该指针可以在SQLite操作期间使用,并永久存储。这个指针通常被用于存储客户端上下文数据,比如在回调函数中访问。

函数原型如下:

void sqlite3_set_clientdata(sqlite3_context*, void*);

函数使用较为简单,第一个参数是指向sqlite3_context结构体的指针,这个指针通常由回调函数提供。第二个参数是一个void类型的指针,这个指针将与sqlite3_context结构体关联。

下面是一个示例,展示如何在sqlite3_create_function()回调函数中使用sqlite3_set_clientdata()来存储客户端上下文数据:

#include <sqlite3.h>
#include <stdio.h>
static void my_function(sqlite3_context *context,int argc,sqlite3_value **argv
) {int count = (int)(intptr_t)sqlite3_get_auxdata(context, 0);  // 从上下文中获取计数器count++;                                                      // 计数器加1sqlite3_set_auxdata(context, 0, (void*)(intptr_t)count);      // 将计数器放回上下文中sqlite3_result_int(context, count);                           // 返回计数器值
}
int main() {sqlite3 *db;sqlite3_open(":memory:", &db);sqlite3_create_function(db, "my_function", -1, SQLITE_ANY, NULL, my_function, NULL, NULL);void *pUserData = malloc(sizeof(int));*(int*)pUserData = 0;sqlite3_set_auxdata(db, 0, pUserData);  // 将计数器存储在数据库连接中sqlite3_context *context = sqlite3_malloc(sizeof(sqlite3_context));sqlite3_set_clientdata(context, db);   // 将数据库连接与上下文关联sqlite3_exec(db, "SELECT my_function()", NULL, NULL, NULL);sqlite3_exec(db, "SELECT my_function()", NULL, NULL, NULL);int count = (int)(intptr_t)sqlite3_get_auxdata(db, 0);printf("function called %d times\n", count);sqlite3_close(db);return 0;
}

该示例通过sqlite3_set_auxdata()函数在数据库连接中存储一个计数器。每次调用my_function()回调函数时,它将自加该计数器并返回该计数器。用sqlite3_set_clientdata()函数将上下文与数据库连接关联。最后,从数据库连接中获取计数器并输出结果。

49.sqlite3_set_last_insert_rowid

sqlite3_set_last_insert_rowid函数用于手动设置最后插入的行ID。通常情况下,SQLite会自动维护最后插入的行ID,无需手动设置。但是,有时候可能需要在想要插入的ID不是递增的情况下手动指定插入行ID。

函数原型如下:

void sqlite3_set_last_insert_rowid(sqlite3*, sqlite3_int64);

第一个参数是指向sqlite3结构体的指针,第二个参数是一个sqlite3_int64类型的整数,代表要设置的最后插入的行ID。

下面是一个示例,展示如何手动设置最后插入的行ID:

#include <sqlite3.h>
#include <stdio.h>
int main() {sqlite3 *db;sqlite3_open(":memory:", &db);sqlite3_exec(db, "CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)", NULL, NULL, NULL);sqlite3_int64 rowid = 10;sqlite3_set_last_insert_rowid(db, rowid);   // 设置最后插入的行IDsqlite3_exec(db, "INSERT INTO test (id, value) VALUES (11, 'hello')", NULL, NULL, NULL);rowid = sqlite3_last_insert_rowid(db);      // 获取最后插入的行IDprintf("last_insert_rowid = %lld\n", rowid);sqlite3_close(db);return 0;
}

在该示例中,我们使用sqlite3_set_last_insert_rowid()函数手动设置了最后插入的行ID为10,然后插入一条ID为11的数据。最后,我们获取最后插入的行ID并将其输出。输出结果为:last_insert_rowid = 10。

这篇关于SQLiteC/C++接口详细介绍之sqlite3类(十五)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/818379

相关文章

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

Apache Ignite 与 Spring Boot 集成详细指南

《ApacheIgnite与SpringBoot集成详细指南》ApacheIgnite官方指南详解如何通过SpringBootStarter扩展实现自动配置,支持厚/轻客户端模式,简化Ign... 目录 一、背景:为什么需要这个集成? 二、两种集成方式(对应两种客户端模型) 三、方式一:自动配置 Thick

C++11范围for初始化列表auto decltype详解

《C++11范围for初始化列表autodecltype详解》C++11引入auto类型推导、decltype类型推断、统一列表初始化、范围for循环及智能指针,提升代码简洁性、类型安全与资源管理效... 目录C++11新特性1. 自动类型推导auto1.1 基本语法2. decltype3. 列表初始化3

C++11右值引用与Lambda表达式的使用

《C++11右值引用与Lambda表达式的使用》C++11引入右值引用,实现移动语义提升性能,支持资源转移与完美转发;同时引入Lambda表达式,简化匿名函数定义,通过捕获列表和参数列表灵活处理变量... 目录C++11新特性右值引用和移动语义左值 / 右值常见的左值和右值移动语义移动构造函数移动复制运算符

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

2025版mysql8.0.41 winx64 手动安装详细教程

《2025版mysql8.0.41winx64手动安装详细教程》本文指导Windows系统下MySQL安装配置,包含解压、设置环境变量、my.ini配置、初始化密码获取、服务安装与手动启动等步骤,... 目录一、下载安装包二、配置环境变量三、安装配置四、启动 mysql 服务,修改密码一、下载安装包安装地

在macOS上安装jenv管理JDK版本的详细步骤

《在macOS上安装jenv管理JDK版本的详细步骤》jEnv是一个命令行工具,正如它的官网所宣称的那样,它是来让你忘记怎么配置JAVA_HOME环境变量的神队友,:本文主要介绍在macOS上安装... 目录前言安装 jenv添加 JDK 版本到 jenv切换 JDK 版本总结前言China编程在开发 Java

Spring Boot Actuator应用监控与管理的详细步骤

《SpringBootActuator应用监控与管理的详细步骤》SpringBootActuator是SpringBoot的监控工具,提供健康检查、性能指标、日志管理等核心功能,支持自定义和扩展端... 目录一、 Spring Boot Actuator 概述二、 集成 Spring Boot Actuat

C++中detach的作用、使用场景及注意事项

《C++中detach的作用、使用场景及注意事项》关于C++中的detach,它主要涉及多线程编程中的线程管理,理解detach的作用、使用场景以及注意事项,对于写出高效、安全的多线程程序至关重要,下... 目录一、什么是join()?它的作用是什么?类比一下:二、join()的作用总结三、join()怎么