加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

SQLite 加入自定义函数

发布时间:2020-12-12 20:16:17 所属栏目:百科 来源:网络整理
导读:简介 : SQLite 内置函数比较有限,有时通过添加自定义函数(User-Defined Fuctions)的方式可以实现一些通过普通 SQL 操作无法实现或者实现很麻烦的功能;也可以替换 SQLite 原有的内置函数,使其符合我们的要求。本文侧重说明在 Android 环境下的做法。 现

简介

SQLite 内置函数比较有限,有时通过添加自定义函数(User-Defined Fuctions)的方式可以实现一些通过普通 SQL 操作无法实现或者实现很麻烦的功能;也可以替换 SQLite 原有的内置函数,使其符合我们的要求。本文侧重说明在 Android 环境下的做法。

现在假设我们现在要在 Android 系统的视频播放器增加一个按照文件扩展名排序的功能,如果不是用自定义函数,就需要先从多媒体数据库中查询出来视频的路径,然后取出视频文件的扩展名并进行排序,因为查询得到的 Cursor 对象不可写,所以需要生成一个 MatrixCursor,把排序后的数据写入,最后返回这个 MatrixCursor。伪代码表示如下:

1 public Cursor getSortedByFileExtensionCursor() {
2     Cursor rawCursor = queryVideoFileNameFromDb(); // 从数据库查询出 id 和路径
3     HashMap<int,String> idAndExtensionMap = getVideoFileExtension(rawCursor); // 获取 id 和扩展名的 HashMap
4     Cursor result = sortAndCreateNewMatrixCursor(idAndExtensionMap); // 对扩展名进行排序,生成 MatrixCursor 作为结果
5     return result;
6 }

而如果我们能够向 SQLite 注册一个自定义函数,很多类似问题就要简单不少。

1. 通过 C 语言接口添加自定义函数

如果使用的是 Android 提供的 sqlite 程序,需要修改 Android 源码目录下的 external/sqlite/android/sqlite3_android.cpp 文件。注册一个自定义函数,函数名称是 get_file_ext,在 SQL 语句中的函数名称是 "_GET_FILE_EXT",简要代码如下:

 1 extern "C" int register_android_functions(sqlite3 * handle,int utf16Storage)
 2 {
 3     // ...
 4     
 5     // 注册自定义函数
 6     err = sqlite3_create_function(handle,"_GET_FILE_EXT",1,SQLITE_UTF8,NULL,get_file_ext,NULL);
 7     if (err != SQLITE_OK) {
 8         return err;
 9     }
10     
11     // ...
12 }
13 
14 // 返回文件扩展名函数的具体实现
15 static void get_file_ext(sqlite3_context * context,int argc,sqlite3_value ** argv) 
16 {
17     // ...
18 }

然后编译 external/sqlite,把编译出来的 libsqlite.so 替换手机 /system/lib/ 下面的库。使用该自定义函数也很简单:

1 public Cursor getSortedByFileExtensionCursor() {
2     // 在 sort by 那里使用我们的 SQLite 自定义函数
3     Cursor result = query("SELECT * FROM video SORT BY _GET_FILE_EXT(_data)");
4 }

Note:如果不是在 Android 环境下,或者无法修改 Android 相关代码,则需要自行通过 c 语言的接口操作数据库,然后同样使用 sqlite3_create_function 这个函数注册自定义函数。如果使用的是 C#/Python/PHP 等语言,这些语言都有相应的 SQLite wrapper,可以类似的操作数据库并注册自定义函数。

2. 通过 Java 语言接口添加自定义函数

Android SQLiteDatabase 类里面有一个添加自定义函数的隐藏接口(@hide),在 Android 源码中编译的话可以使用该接口,使用方法大致如下:

 1 public class DatabaseHelper extends SQLiteOpenHelper {
 2     public DatabaseHelper(Context context,String name,SQLiteDatabase.CursorFactory factory,int version) {
 3         super(context,name,factory,version);
 4     }
 5     
 6     @Override
 7     public void onOpen(SQLiteDatabase db) {
 8         db.addCustomFunction("_GET_FILE_EXT",1,mGetFileExtension);
 9     }
10     
11     private final SQLiteDatabase.CustomFunction mGetFileExtension =
12             new SQLiteDatabase.CustomFunction() {
13         @Override
14         public void callback(String[] args) {
15             String file = args[0];
16             int index = file.lastIndexOf(".");
17             if (index != -1 && file.length() > index + 1) {
18                 return file.substring(index);
19             }
20             return null;
21         }
22     };
23 }

然后对这个数据库进行查询操作时,就可以使用我们添加的 _GET_FILE_EXT 函数了。Android 源码目录下的 pacakges/providers/MediaProvider 这个程序就使用了此接口,可以参考。

Note:对外发布的程序最好不要依赖隐藏的 Java 接口,兼容性难以保证。

扩展阅读:

  • Create Or Redefine SQL Functions:创建自定义函数的解释。
  • Quickstart:使用 c 语言接口打开 SQLite 数据库的简单示例代码。

转载请注明出处:http://www.cnblogs.com/imouto/archive/2013/06/14/how-to-add-user-defined-functions-for-sqlite.html

本文外部镜像:http://oteku.blogspot.com/2013/06/how-to-add-user-defined-functions-for-sqlite.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读