扩展C API

扩展API提供几种扩展或定制SQLite的基本方法,包括:创建用户自定义函数、聚合、排序规则和虚拟表,还可以在更底层实现一些方法,像虚拟文件系统,启动时可换的页缓存、内存分配和互斥的实现。

用户自定义函数是用户编写的用于特定应用的SQL函数,可以在SQL语句中调用他们。

聚合是一种特殊形式的函数,他与普通函数的工作方式基本相同,只是他对一组记录j进行操作并返回这一组记录中某个特定的字段的聚合值或表达式计算值,聚合函数可以从多个字段进行计算,而普通函数对单个记录进行操作。SQL中标准的聚合COUNT()、SUM()、AVG()。
排序规则是对文本进行比较和排序的方法。SQLite中默认的排序规则是BINARY,它通过memcmp()逐字节进行比较。仅适用于UTF-8编码。因此SQLite构建自定义排序规则以处理这些语言。

一、API

实现函数、聚合以及排序规则的基本方法都是使用回调函数,并在程序中注册,注册之后就可以在SQL中使用。函数和聚合使用相同的注册函数和类似的回调函数。虽然排序规则使用单独的注册函数,但是与函数和聚合的注册函数基本相同。

用户自定义聚合、函数和排序规则的生命周期是短暂的。他们是基于连续注册的,而且不存储在数据库中而是在程序中,需要确定用户已加载了定制并在连接中注册。扩展必须在每一个使用他们的连接上做。

1.注册函数
使用sqlite3_create_function()在连接中注册函数和聚合

函数:int sqlite3_create_function(sqlite3 *cnx, const char *zfunctionname, int narg, int etextrep, void *puserdata, void (*xfunc)(sqlite3_context*,int,sqlite3_value**), void (*xstep)(sqlite3_context*,int,sqlite3_value**), void (*xfinal)(sqlite3_context*));
参数:cnx:数据库连接句柄zfunctionname:将在SQL中调用的函数名称narg:自定义函数参数个数,如果是-1,SQLite允许参数个数可变etextrep:首先文本编码,SQLITE_UTF8、SQLITE_UTF16BE, SQLITE_UTF16LE、SQLITE_ANY(万能的)。puserdata:应用程序数据。该数据可供xfunc、xstep、xfinal指定的回调函数中使用xfunc:回调函数,SQL函数的真实实现,用户定义函数只需要提供该函数的回调函数,让xstep、xfinal函数指针为NULL,后两个是给聚合实现使用的。xstep:聚合步骤函数,SQLite每次处理聚合结果集中的一行都要使用xstep,以便聚合处理该行的相关字段值,并将其包含在聚合计算的结果中。xfinal:finalize聚合函数,处理完之后,SQLite调用该函数进行整个聚合汇总处理,该函数通常由计算最终值和可选的情况b部分组成。

2.步骤函数

函数:void fn(sqlite3_context* ctx, int narg, sqlite3_value** values);
参数:ctx:函数/聚合上下文环境。它保持特殊函数的实例状态,可以通过sqlite3_create_function()中的参数puserdata获取到。
narg:传递给函数的参数个数
values:sqlite3_value结构体数组,SQLite实际参数值的句柄。

二、函数

假设已实现函数hello_world();下面是示例

 void hello_world(sqlite3_context* ctx, int nargs, sqlite3_value** values){const char *msg;msg = sqlite3_mprintf("hello %s", sqlite3_value_text(values[0]));sqlite3_result_text(ctx, msg, strlen(msg), sqlite3_free);}int main(){int rc,;sqlite3 *db;sqlite3_open_v2("test.db", &db);sqlite3_create_function(db, "hello_world", 1, SQLITE_UTF8, NULL, hello_world, NULL, NULL);print_sql_result(db, "select hello_world('CHINA')");sqlite3_close(db);return 0;}

其中print_sql_result函数只是简单封装sqlite3_prepare_v2的简单封装并将结果打印出来。sqlite3_result_text()是sqlite3_result_xxx()系列函数,用来为用户自定义函数和聚合返回值的。

错误处理函数

函数:void sqlite3_result_error(sqlite3_context* ctx, const char *msg, int len);
参数:ctx:函数上下文msg:错误消息保存buflen:错误消息长度

返回输入值

函数:sqlite3_result_value(sqlite3_context* ctx, sqlite3_value* value);
功能:将某个参数以相同的形式作为返回值传递回去
参数:ctx:函数上下文value:参数值

三、聚合
聚合比用户自定义函数稍微复杂一点,因为聚合有两个回调函数,一个是步骤函数计算进行中的值,另一个是finalize函数完成最终计算和清理工作。下图是一般处理过程:

聚合和函数使用同一个注册函数sqlite3_create_function();聚合不需要为xfunc提供回调函数,设为NULL即可。

实例:
假定str_agg_step 和 str_agg_finalize 分别是xstep 和 xfinal 回调函数以实现。

int main()
{int rc;sqlite3 *db;char *sql = NULL;sqlite3_open_v2("test.db", &db);sqlite3_create_function(db, "str_agg", 1, SQLITE_UTF8, db, NULL, str_agg_step, str_agg_finalize);sql = "select season, str_agg(name, ', ') from episodes group by season";print_sql_result(db, sql);sqlite3_close(db);return 0;
}

四、排序规则

排序规则是对事物进行分类比较,那么当遇到不同类型的值的时候如何排序呢?SQLite对结果集中的字段排序时,第一件事就是根据存储类对字段值进行排序,然后在每种类型中进行排序,存储类型进行排序的顺序从前让后如下所示:

  1. NULL值

  2. INTEGER和REAL值

  3. TEXT值

  4. BLOB值

排序法定义:与逐个比特比较数字代码相反,排序规则使用语言敏感的规则对文本进行比较。

排序规则如何工作:通常来讲,排序方法对将要比较的两个字符串进行切分,通过排序序列逐以比较每个字符。从左到右比较字符。如果一个字符的数字值大于另一个,比较结束,有较大数字值的字符串是较大者。如果相同则继续比较下一个字符。直到发现不同,如果比完所以字符还未分出大小,那么由排序规则决定这种情况如何处理。

标准排序规则类型:SQLite中唯一内置的排序规则binary使用标准的C函数库memcmp()比较两个字符串,binary排序规则对英文文本使用很好,但是对于其他语言可以使用nocase,它对大小写不敏感。排序规则是通过表字段或索引定义以及在查询中指定的方法和字段关联起来。
例如:在foo中创建大小写不敏感的bar字段

create table foo (bar text collate nocase, baz nocase);

这时只要SQLite处理bar字段时,就会使用nocase排序规则,如果不想将排序规则附加到数据库对象上,而是需要时在查询中指定,可以直接在查询中指定如:

select cast(baz) collate nocase as baz_as_text from foo order by baz_as_text;

排序注册函数

函数:sqlite3_create_collation_v2(sqlite3 *db, const char *zname, int pref16, void* puserdata, int(*xcompare)(void*,int,const void*,int,const void*)void(*xdestory)(void*));
参数:db:数据库句柄zname:SQL语句中使用的排序规则名称pref16:编码格式puserdata:应用程序数据compare:int compare(void *data, int len1, const void* str1, int len2, const void* str2);参数:data:应用程序数据len1:字符串1长度str1:字符串1len2:字符串2长度str2:字符串2返回值:字符串1 < 字符串2 返回值小于0字符串1 = 字符串2 返回值0字符串1 > 字符串2 返回值大于0

按需排序
SQLite提供一种直到实际需要时才注册排序的延迟方式,因此,如果您不确定程序的排序规则,可以使用函数sqlite3_collation_needed(),将注册延迟到最后可能需要的时刻,只需要提供回调函数,SQLite会在需要时注册未知排序规则。

函数:int sqlite3_collation_needed(sqlite3 *db, void *data, void(*crf)(void*,sqlite3*,int etextrep,const char*));
参数:db:数据库句柄data:应用程序数据crf:void crf(void *data, sqlite3 *db, int etextrep, const char*);参数:data:应用程序数据db:数据库句柄etextrep:编码格式const char*:排序规则名称

SQLite3扩展C API相关推荐

  1. 扩展Kubernetes API

    目录 自定义资源定义 创建和部署自定义资源定义 定制控制器 Operator开发 Kubernetes示例控制器 Operator Framework 创建和部署Kubernetes Operator ...

  2. windows访问uvc摄像头扩展单元api库分享

    分享一个自己封装的windows通过dshow接口访问uvc扩展单元的dll库,采用vs2017编译,分别编译了x86,x64的debug和release版本,可直接调用,api调用方法如下: (1) ...

  3. trello_如何构建Trello Chrome扩展程序-API身份验证

    trello 在SitePoint,我们广泛使用Trello. 当然,它有其独特之处,可以在各个领域使用一两个改进,但是在大多数情况下,它彻底改变了工作人员,作者及其编辑的协作经验. 我最近发现自己需 ...

  4. 如何构建Trello Chrome扩展程序-API身份验证

    在SitePoint,我们广泛使用Trello. 当然,它有其独特之处,可以在各个领域使用一两个改进,但是在大多数情况下,它彻底改变了工作人员,作者及其编辑的协作经验. 我最近发现自己需要从非会员的特 ...

  5. Chrome扩展全部API

    原文:http://www.ituring.com.cn/article/75729 稳定API 名称 描述 最低版本 alarms 使用 chrome.alarms API 安排代码周期性地或者在将 ...

  6. OpenStack 之Nova添加扩展API流程,附带资源的查找功能

    例子中涉及到SQLAlchemy 得相关操作,可以参考 上一随笔 Openstack 中规定,扩展openstack得api有两种方式 创建新的WSGI 资源 扩展原有得WSGI资源得控制器(我得理解 ...

  7. 带你玩转kubernetes-k8s(第54篇-Kubernetes之使用API聚合机制扩展API资源)

    API聚合机制是Kubernetes 1.7版本引入的特性,能够将用户扩展的API注册到kube-apiserver上,仍然通过API Server的HTTP URL对新的API进行访问和操作.为了实 ...

  8. 使用Aggregated APIServer扩展你的kubernetes API

    Overview What is Kubernetes aggregation Kubernetes apiserver aggregation AA 是Kubernetes提供的一种扩展API的方法 ...

  9. 常见软件---SQLite3的C语言下使用

    使用背景 最近在研究Wazuh的时候,发现服务端默认也使用了sqlite,原以为只有嵌入式使用,其实在这种本地化的软件中,使用sqlite也是一种很好的选择,至少软件的依赖性就少了很多,sqlite可 ...

最新文章

  1. 垃圾热解气化工艺的电气、仪表及控制系统设计
  2. php面试hr要看你的项目,昨晚hr给了我一个面试题,说过了就安排我面试
  3. Tools: geos 使用指南
  4. win2008r2 or centos6 硬盘挂载
  5. 封装scrollView 循环滚动,tableViewCell(连载) mvc
  6. npm notice created a lockfile as package-lock.json. You should commit this file.
  7. 什么叫做数字功放?它的电路原理是什么?
  8. CocoaPods管理iOS项目 2018年11月06日
  9. 循环 计算数值的整数次幂
  10. c语言 判断一个图是否全连通_【连载】(判断执行语句)乐创DIY C语言讲义——3.8节(2)...
  11. C++笔试题整理(一)
  12. java wait() notify_Java的wait(), notify()和notifyAll()使用小结
  13. redis双写一致性问题
  14. qi接收启动协议_无线充电Qi通信协议分析
  15. c语言调用pdf文档,使用PDFLib生成PDF文档方法介绍(C语言版)
  16. Android模仿新浪微博(自定义ListView下拉刷新)
  17. 计算机专业大学毕业找不到工作,再去Java培训机构学习可靠吗?
  18. hutool生成二维码
  19. unity3d绘画手册-------地形高度调节
  20. 微信小程序的开发使用第三方组件库

热门文章

  1. Maven 多环境配置profile
  2. MySql字符串与时间日期之间的的转换
  3. matlab无穷积分求解_python做微积分
  4. java 账户和密码 3次_模拟登录,给三次机会,并提示还有几次。Java实现
  5. Using LogMiner
  6. python web access_利用python分析access日志的方法
  7. android adb移植到arm,android-ndk – 为arm处理器构建android adb
  8. oracle unpivot 索引_Oracle 行转列pivot 、列转行unpivot 的Sql语句总结
  9. restTemplate请求,报 : No instances avaliable for ip地址
  10. 生产者消费者模式-java原生、Disruptor实现方案