Show HN: 使用 JavaScript 扩展你的 SQLite 数据库 - SQLite JavaScript
sqliteai/sqlite-js
main BranchesTags Go to file Code
Folders and files
Name| Name| Last commit message| Last commit date
---|---|---|---
Latest commit
History
34 Commits
.github/workflows| .github/workflows
libs| libs
src| src
test| test
.gitignore| .gitignore
Makefile| Makefile
README.md| README.md
View all files
Repository files navigation
SQLite-JS Extension
SQLite-JS 是一个强大的扩展,它为 SQLite 带来了 JavaScript 的能力。 通过此扩展,你可以使用 JavaScript 代码创建自定义 SQLite 函数、聚合函数、窗口函数和排序规则,从而可以直接在 SQLite 数据库中进行灵活而强大的数据操作。
Table of Contents
- Installation
- Functions Overview
- Scalar Functions
- Aggregate Functions
- Window Functions
- Collation Sequences
- Sync JavaScript Functions Across Devices
- JavaScript Evaluation
- Examples
- Update Functions
- Building from Source
- License
Installation
Pre-built Binaries
从官方的 Releases 页面下载适合你平台的预构建二进制文件:
- Linux: x86 and ARM
- macOS: x86 and ARM
- Windows: x86
- Android
- iOS
Loading the Extension
-- In SQLite CLI
.load ./js
-- In SQL
SELECT load_extension('./js');
Functions Overview
SQLite-JS 提供了几种使用 JavaScript 扩展 SQLite 功能的方法:
Function Type | Description
---|---
Scalar Functions | 处理单个行并返回单个值
Aggregate Functions | 处理多行并返回单个聚合结果
Window Functions | 类似于聚合函数,但可以访问完整的数据集
Collation Sequences | 定义文本值的自定义排序顺序
JavaScript Evaluation | 直接在 SQLite 中评估 JavaScript 代码
Scalar Functions
标量函数一次处理一行并返回单个值。 它们对于数据转换、计算、文本操作等非常有用。
Usage
SELECT js_create_scalar('function_name', 'function_code');
Parameters
- function_name : 自定义函数的名称
- function_code : 定义函数的 JavaScript 代码。 必须采用
function(args) { /* your code here */ }
的形式
Example
-- Create a custom function to calculate age from birth date
SELECT js_create_scalar('age', 'function(args) {
const birthDate = new Date(args[0]);
const today = new Date();
let age = today.getFullYear() - birthDate.getFullYear();
const m = today.getMonth() - birthDate.getMonth();
if (m < 0 || (m === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
return age;
}');
-- Use the function
SELECT name, age(birth_date) FROM people;
Aggregate Functions
聚合函数处理多行并计算单个结果。 示例包括标准 SQL 中的 SUM、AVG 和 COUNT。
Usage
SELECT js_create_aggregate('function_name', 'init_code', 'step_code', 'final_code');
Parameters
- function_name : 自定义聚合函数的名称
- init_code : 初始化聚合变量的 JavaScript 代码
- step_code : 处理每一行的 JavaScript 代码。 必须采用
function(args) { /* your code here */ }
的形式 - final_code : 计算最终结果的 JavaScript 代码。 必须采用
function() { /* your code here */ }
的形式
Example
-- Create a median function
SELECT js_create_aggregate('median',
-- Init code: initialize an array to store values
'values = [];',
-- Step code: collect values from each row
'function(args) {
values.push(args[0]);
}',
-- Final code: calculate the median
'function() {
values.sort((a, b) => a - b);
const mid = Math.floor(values.length / 2);
if (values.length % 2 === 0) {
return (values[mid-1] + values[mid]) / 2;
} else {
return values[mid];
}
}'
);
-- Use the function
SELECT median(salary) FROM employees;
Window Functions
窗口函数(如聚合函数)对一组行进行操作。 但是,他们可以访问当前窗口中的所有行,而无需将它们折叠为单个输出行。
Usage
SELECT js_create_window('function_name', 'init_code', 'step_code', 'final_code', 'value_code', 'inverse_code');
Parameters
- function_name : 自定义窗口函数的名称
- init_code : 初始化变量的 JavaScript 代码
- step_code : 处理每一行的 JavaScript 代码。 必须采用
function(args) { /* your code here */ }
的形式 - final_code : 计算最终结果的 JavaScript 代码。 必须采用
function() { /* your code here */ }
的形式 - value_code : 返回当前值的 JavaScript 代码。 必须采用
function() { /* your code here */ }
的形式 - inverse_code : 从当前窗口中删除行的 JavaScript 代码。 必须采用
function(args) { /* your code here */ }
的形式
Example
-- Create a moving average window function
SELECT js_create_window('moving_avg',
-- Init code
'sum = 0; count = 0;',
-- Step code: process each row
'function(args) {
sum += args[0];
count++;
}',
-- Final code: not needed for this example
'function() { }',
-- Value code: return current average
'function() {
return count > 0 ? sum / count : null;
}',
-- Inverse code: remove a value from the window
'function(args) {
sum -= args[0];
count--;
}'
);
-- Use the function
SELECT id, value, moving_avg(value) OVER (ORDER BY id ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
FROM measurements;
Collation Sequences
排序规则确定如何在 SQLite 中比较和排序文本值。 自定义排序规则支持高级排序功能,如自然排序、特定于区域设置的排序等。
Usage
SELECT js_create_collation('collation_name', 'collation_function');
Parameters
- collation_name : 自定义排序规则的名称
- collation_function : 比较两个字符串的 JavaScript 代码。 如果第一个字符串小于第二个字符串,则必须返回一个负数;如果它们相等,则返回零;如果第一个字符串大于第二个字符串,则返回一个正数。
Example
-- Create a case-insensitive natural sort collation
SELECT js_create_collation('natural_nocase', 'function(a, b) {
// Extract numbers for natural comparison
const splitA = a.toLowerCase().split(/(\d+)/);
const splitB = b.toLowerCase().split(/(\d+)/);
for (let i = 0; i < Math.min(splitA.length, splitB.length); i++) {
if (splitA[i] !== splitB[i]) {
if (!isNaN(splitA[i]) && !isNaN(splitB[i])) {
return parseInt(splitA[i]) - parseInt(splitB[i]);
}
return splitA[i].localeCompare(splitB[i]);
}
}
return splitA.length - splitB.length;
}');
-- Use the collation
SELECT * FROM files ORDER BY name COLLATE natural_nocase;
Syncing Across Devices
当与 sqlite-sync 一起使用时,通过 sqlite-js 创建的用户定义函数会自动在 SQLite Cloud 集群中复制,从而确保所有连接的对等方共享相同的逻辑和行为 - 即使离线也是如此。 要启用自动持久化并同步,必须执行特殊的 js_init_table
函数。
Usage
SELECT js_init_table(); -- Create table if needed (no loading)
SELECT js_init_table(1); -- Create table and load all stored functions
JavaScript Evaluation
该扩展还提供了一种直接在 SQLite 查询中评估 JavaScript 代码的方法。
Usage
SELECT js_eval('javascript_code');
Parameters
- javascript_code : 要评估的任何有效的 JavaScript 代码
Example
-- Perform a calculation
SELECT js_eval('Math.PI * Math.pow(5, 2)');
-- Format a date
SELECT js_eval('new Date(1629381600000).toLocaleDateString()');
Examples
Example 1: String Manipulation
-- Create a function to extract domain from email
SELECT js_create_scalar('get_domain', 'function(args) {
const email = args[0];
return email.split("@")[1] || null;
}');
-- Use it in a query
SELECT email, get_domain(email) AS domain FROM users;
Example 2: Statistical Aggregation
-- Create a function to calculate standard deviation
SELECT js_create_aggregate('stddev',
'sum = 0; sumSq = 0; count = 0;',
'function(args) {
const val = args[0];
sum += val;
sumSq += val * val;
count++;
}',
'function() {
if (count < 2) return null;
const variance = (sumSq - (sum * sum) / count) / (count - 1);
return Math.sqrt(variance);
}'
);
-- Use it in a query
SELECT department, stddev(salary) FROM employees GROUP BY department;
Example 3: Custom Window Function
-- Create a window function to calculate percentile within a window
SELECT js_create_window('percentile_rank',
'values = [];',
'function(args) {
values.push(args[0]);
}',
'function() {
values.sort((a, b) => a - b);
}',
'function() {
const current = values[values.length - 1];
const rank = values.indexOf(current);
return (rank / (values.length - 1)) * 100;
}',
'function(args) {
const index = values.indexOf(args[0]);
if (index !== -1) {
values.splice(index, 1);
}
}'
);
-- Use it in a query
SELECT name, score,
percentile_rank(score) OVER (ORDER BY score)
FROM exam_results;
Update Functions
由于 SQLite 中的一个约束,无法使用用于最初注册用户定义函数的同一数据库连接来更新或重新定义用户定义函数。 要修改现有的 JavaScript 函数,必须通过单独的数据库连接执行更新。
Building from Source
# Build for your current platform
make
# Build for a specific platform
make PLATFORM=macos
make PLATFORM=linux
make PLATFORM=windows
# Install
make install
License
此项目已获得 MIT 许可 - 有关详细信息,请参见 LICENSE 文件。
About
Create custom SQLite functions in JavaScript. Extend your database with scalars, aggregates, window functions, and collations directly in JavaScript. sqlite.ai
Resources
Readme Activity Custom properties
Stars
Watchers
Forks
Releases 3
1.1.2 Latest Apr 15, 2025 + 2 releases
Packages 0
No packages published
Contributors 2
Languages
Footer
Footer navigation
You can’t perform that action at this time.