
关系型数据库数据库前端【免费下载链接】lovefieldLovefield is a relational database for web apps. Written in JavaScript, works cross-browser. Provides SQL-like APIs that are fast, safe, and easy to use.项目地址https://gitcode.com/gh_mirrors/lov/lovefield点击查看免费下载Lovefield 是一个用 JavaScript 编写、跨浏览器运行的 Web 端关系型数据库提供 SQL 风格的链式 API。本篇技术指南以仓库中的demos/todo_typescript示例为主线完整讲解如何从环境准备、依赖安装、TypeScript 类型声明到 schema 定义、数据库连接、插入与查询亲手跑通一个Lovefield TypeScript的最小 Todo 应用读完你将掌握 Lovefield 在 TypeScript 项目中的标准接入姿势并理解其底层 Builder、TableBuilder 与查询构建器的真实实现机制。示例概览一个最小的 Lovefield TypeScript 应用demos/todo_typescript是 Lovefield 官方仓库提供的 TypeScript 快速入门示例其核心目标只有一个用最少的代码演示在 TypeScript 中完成 Lovefield 的建表—连接—插入—查询完整闭环。整个示例由 6 个文件构成职责清晰文件作用todo.tsTypeScript 源码定义 schema、连接数据库、执行插入与查询todo.html页面入口加载 Lovefield 运行时与编译产物 todo.jspackage.jsonnpm 依赖清单gulp 构建链、typings、lovefield 等typings.jsonTypeScript 全局类型声明依赖es6-promise、lovefieldgulpfile.js定义typings、build、debug三个构建/调试任务README.md官方给出的 5 步运行指引页面端 todo.html 的加载方式值得注意它直接通过script srcnode_modules/lovefield/dist/lovefield.min.js引入 npm 安装的 Lovefield 压缩运行时随后加载 TypeScript 编译产物todo.js页面标题也点明了用途——Minimal example of using Lovefield。这意味着 TypeScript 源码只负责类型安全与编译期检查真正的数据库引擎仍由 Lovefield 运行时提供。环境准备官方 5 步运行流程官方 READMEdemos/todo_typescript/README.md给出了 5 个步骤逐一拆解如下# 1. 安装 gulp若尚未安装用于执行构建与本地调试任务 npm install -g gulp # 2. 安装 typings 与 tsc若尚未安装 # tscTypeScript 编译器负责把 todo.ts 编译成 todo.js # typings旧版 TypeScript 类型声明管理器用于拉取全局 .d.ts 声明 npm install -g tsc typings # 3. 拉取 package.json 中声明的依赖 npm install # 4. 启动本地 Web 服务器内部先执行 typings build再起 webserver gulp debug # 5. 浏览器访问 # http://localhost:8000/todo.html从步骤可以看出该示例采用的是全局命令行工具 本地依赖的组合模式gulp、tsc、typings属于全局工具而gulp-typescript、gulp-typings、gulp-webserver、lovefield等属于devDependencies本地依赖。默认端口为 8000gulp debug任务内部支持通过--port参数覆盖详见下文 gulpfile 解析。依赖与类型声明package.json 与 typings.json示例的 package.json 将lovefield本身声明为devDependencies版本^2.1.8并配套了完整的 gulp 工具链{ name: todo, version: 0.0.1, description: Quick-start todo example in TypeScript., main: todo.html, license: http://www.apache.org/licenses/LICENSE-2.0, devDependencies: { gulp: ^3.9.0, gulp-typescript: ^2.13.0, gulp-typings: ^2.0.0, gulp-webserver: ^0.9.1, lovefield: ^2.1.8, nopt: ^3.0.6, typings: ^1.0.4 } }各依赖分工如下gulp任务流编排串联类型声明拉取、TS 编译与静态服务器gulp-typescript在 gulp 流中调用 tsc 编译todo.tsgulp-typings / typings按typings.json拉取全局类型声明gulp-webserver启动带目录列表的本地静态服务器nopt解析gulp debug的命令行参数如--portlovefield浏览器端数据库运行时本体。而 typings.json 声明了 2 个全局类型包{ globalDependencies: { es6-promise: registry:dt/es6-promise#0.0.020160423074304, lovefield: registry:dt/lovefield#2.0.6220160317120654 } }其中es6-promise提供 Promise 的类型定义Lovefield 的connect()、exec()均返回 thenablelovefield则提供lf.*命名空间下全部 API 的类型声明。二者都会落盘到 todo.ts 顶部/// reference path指令所指向的typings/目录中从而让 tsc 能对lf.schema.create、lf.Type.INTEGER等符号做静态类型检查。gulpfile.js 解析typings、build、debug 三个任务的协作gulpfile.js 定义了三个 gulp 任务构成完整的拉声明 → 编译 → 起服务流水线任务 1typings——按typings.json安装全局类型声明gulp.task(typings, function() { return gulp.src(typings.json).pipe(typings()); });任务 2build——以typings为前置依赖将todo.ts编译为todo.jsgulp.task(build, [typings], function() { var tsResult gulp.src(todo.ts) .pipe(ts({ noEmitOnError: true, // 编译报错时不产出 JS避免运行期出错 noImplicitAny: true, // 开启隐式 any 检查强制显式标注类型 out: todo.js // 合并输出为单文件 todo.js })); return tsResult.js.pipe(gulp.dest(.)); });注意这里开启了noEmitOnError: true与noImplicitAny: true前者保证类型错误时不会生成损坏的todo.js后者要求所有变量/参数显式声明类型。这也是示例源码中频繁出现lf.schema.Builder、lf.Database、lf.schema.Table、lf.schema.Column等显式类型标注的原因。任务 3debug——以build为前置依赖启动静态服务器gulp.task(debug, [build], function() { var knownOps { port: [Number, null] }; var portNumber nopt(knownOps).port || 8000; // 默认端口 8000 gulp.src(.).pipe(webserver({ directoryListing: true, // 开启目录列表便于直接浏览 todo.html open: false, port: portNumber })); });debug默认监听 8000 端口如需换端口可执行gulp debug --port 9000由 nopt 解析。directoryListing: true意味着访问根路径时可看到目录下的所有文件方便直接点击进入todo.html。todo.ts 源码逐段精读完整的数据流todo.ts 是整个示例的灵魂共分四个阶段定义 schema → 连接数据库 → 插入记录 → 条件查询。下面分段讲解。阶段一定义 schema——建库、建表、加索引function main(): void { var schemaBuilder: lf.schema.Builder lf.schema.create(todo, 1); schemaBuilder.createTable(Item). addColumn(id, lf.Type.INTEGER). addColumn(description, lf.Type.STRING). addColumn(deadline, lf.Type.DATE_TIME). addColumn(done, lf.Type.BOOLEAN). addPrimaryKey([id], false). addIndex(idxDeadline, [deadline], false, lf.Order.DESC);lf.schema.create(todo, 1)创建名为todo、版本号为1的 schema 构建器。从源码 lib/schema/builder.js 可见lf.schema.create只是new lf.schema.Builder(dbName, dbVersion)的全局便捷入口Builder 内部会构造一个lf.schema.DatabaseSchema并维护一张tableBuilders_映射表。createTable(Item)注册名为Item的表构建器从 lib/schema/builder.js 的实现看重复建同名表会抛出异常码 503Name {0} is already defined且 schema 一旦finalized即已调用过getSchema()/connect()就不允许再建表异常码 535。addColumn依次声明 4 列类型分别为lf.Type.INTEGER、lf.Type.STRING、lf.Type.DATE_TIME、lf.Type.BOOLEAN。查看 lib/schema/table_builder.js 的实现会发现addColumn会先做命名规则与重名检查并且对默认允许为 NULL 的类型如字符串、日期时间自动调用addNullable——这解释了为什么示例中只有主键id被隐式视为不可空。addPrimaryKey([id], false)将id设为主键第二个参数false表示不使用自增auto increment。从 lib/schema/table_builder.js 看主键本质上是自动创建了一个名为pkItempk 表名帕斯卡化的唯一索引。addIndex(idxDeadline, [deadline], false, lf.Order.DESC)为deadline列创建降序索引。其签名对应 lib/schema/table_builder.js 的addIndex(name, columns, opt_unique, opt_order)opt_unique默认为falseopt_order默认为lf.Order.ASC本例显式传入了lf.Order.DESC。阶段二连接数据库——选择内存存储引擎var todoDb: lf.Database null; var dummyItem: lf.schema.Table null; var connectOptions: lf.schema.ConnectOptions { storeType: lf.schema.DataStoreType.MEMORY }; schemaBuilder.connect(connectOptions).then( function(db) { todoDb db; dummyItem db.getSchema().table(Item); ...ConnectOptions中的storeType: lf.schema.DataStoreType.MEMORY明确指定内存型后端数据随页面关闭而消失这是演示场景最合适的选择。Lovefield 的存储层在 lib/backstore 目录下还提供了IndexedDB、WebSQL、LocalStorage等后端实现如需持久化可改为lf.schema.DataStoreType.INDEXED_DB。底层机制上connect()由 lib/schema/builder.js 实现它会先做连接状态检查已连接/连接中时抛出异常码 113随后调用lf.proc.Database的init(opt_options)返回 Promise。connect()成功后通过db.getSchema().table(Item)获取Item表的运行时对象即dummyItem供后续createRow、insertOrReplace、select使用。阶段三插入记录——createRow 与 insertOrReplacevar row dummyItem.createRow({ id: 1, description: Get a cup of coffee, deadline: new Date(), done: false }); return db.insertOrReplace().into(dummyItem).values([row]).exec();createRow将普通 JS 对象包装成 Lovefield 行对象字段名与 schema 列一一对应其中deadline传入的是new Date()对应lf.Type.DATE_TIME列。db.insertOrReplace()生成一个InsertBuilderinto(dummyItem)指定目标表values([row])传入行数组exec()执行写入。注意示例选用的是insertOrReplace而非insert——两者的差异在 lib/query/insert_builder.js 中有明确实现InsertBuilder构造时以opt_allowReplace区分insertOrReplace()即allowReplace true的版本执行前会断言into与values均已设置异常码 518并且当allowReplace为 true 时目标表必须存在主键否则抛出异常码 519——示例中Item表恰好声明了id主键因此合法。阶段四条件查询——select 与 where 的链式调用}).then( function() { var column: lf.schema.Column (anydummyItem).done; return todoDb.select().from(dummyItem).where(column.eq(false)).exec(); }).then( function(results) { results.forEach(function(row) { console.log((anyrow).description, before, (anyrow).deadline); document.body.textContent (anyrow).description before (anyrow).deadline; }); });todoDb.select()创建 SelectBuilderfrom(dummyItem)指定查询表where(column.eq(false))过滤done false的记录exec()返回 Promiseresolve 出结果数组。由于dummyItem是lf.schema.Table类型而非强类型化的列对象源码用(anydummyItem).done绕过类型限制取到done列再用lf.schema.Column.eq(false)构造等值谓词。查询结果遍历时同样以(anyrow).description的方式读取行字段并把结果写入document.body.textContent最终页面会显示 Get a cup of coffee before 时间 字样验证整条数据链路。从构建器实现看lib/query/select_builder.js 的assertExecPreconditions会在执行前校验from已设置异常码 522以及 limit/skip 绑定参数是否合法异常码 523where谓词与查询计划则交由 lib/proc 目录下的逻辑/物理计划生成器与PushDownSelectionsPass等重写器处理。整个 API 是异步 Promise 链示例中connect → insertOrReplace → select三个阶段依次串联在.then()回调里保证前序写操作完成后再发起查询。运行效果与验证方式按前文 5 步操作后浏览器打开http://localhost:8000/todo.html即可看到查询结果文本默认只有一条donefalse的待办项被选中输出。可以用以下几种方式验证示例确实按预期工作观察控制台todo.ts中console.log((anyrow).description, before, (anyrow).deadline)会在 DevTools Console 打印记录内容修改存储后端把connectOptions.storeType改为lf.schema.DataStoreType.INDEXED_DB刷新页面后数据持久存在可验证 Lovefield 多后端切换能力对应 lib/backstore 的 IndexedDB 实现扩展数据在values([row])中追加更多createRow产物或把where条件改为eq(true)观察筛选结果变化体会lf.Order.DESC索引对deadline查询排序的影响。从示例到源码Lovefield 类型系统与构建器的关键事实为便于读者继续深入这里把示例背后可验证的源码事实集中列出lf.schema.create是 Builder 的全局入口lib/schema/builder.js 中lf.schema.create function(dbName, dbVersion) { return new lf.schema.Builder(dbName, dbVersion); }Builder 内部持有DatabaseSchema与各表的TableBuilder集合。schema 有已定稿状态Builder 的getSchema()会触发一次finalize_()此后createTable将抛出异常码 535connect()期间重复连接会抛异常码 113见 lib/schema/builder.js。主键/唯一约束在底层都表现为索引addPrimaryKey自动生成pk 表名的唯一索引并登记进uniqueIndices_lib/schema/table_builder.jsaddIndex的opt_unique参数决定该索引是否唯一lib/schema/table_builder.js。插入/替换语义由 InsertBuilder 的allowReplace标志控制且替换操作强制要求目标表存在主键否则抛异常码 519lib/query/insert_builder.js。查询 API 是 Promise 驱动lf.Database接口lib/database.js统一声明了select/insert/insertOrReplace/update/delete/observe/unobserve/createTransaction/close/export/import等操作示例所用的getSchema、select、insertOrReplace均在此接口之上。小结demos/todo_typescript以最小成本展示了 Lovefield 在 TypeScript 生态中的完整接入路径全局工具gulp、tsc、typings负责构建链typings.json补齐lf.*的类型声明todo.ts用链式 API 走通建 schema → 连接内存库 → 插入 → 条件查询四个环节底层则有 Builder/TableBuilder/InsertBuilder/SelectBuilder 等模块提供严格的执行前置校验。理解了这条主线后续无论是接入 IndexedDB 持久化、构造多表 join 查询还是使用observe实现响应式 UI都可以在此基础上平滑展开。赞分享关系型数据库数据库前端【免费下载链接】lovefieldLovefield is a relational database for web apps. Written in JavaScript, works cross-browser. Provides SQL-like APIs that are fast, safe, and easy to use.项目地址https://gitcode.com/gh_mirrors/lov/lovefield点击查看免费下载相关推荐Lovefield 完全指南纯 JavaScript 关系型数据库的 Schema 建模、SQL 风格查询与跨浏览器存储实践Lovefield 完全指南纯 JavaScript 关系型数据库的 Schema 建模、SQL 风格查询与跨浏览器存储实践 Lovefield 是一个用纯关系型数据库数据库前端Lovefield完整指南如何在浏览器中构建强大的关系型数据库Lovefield完整指南如何在浏览器中构建强大的关系型数据库 Lovefield是一个纯JavaScript编写的关系型数据库专为Web应用设计。它提供S关系型数据库数据库前端Lovefield 设计文档全解读浏览器关系型数据库的架构、查询引擎与存储引擎设计Lovefield 设计文档全解读浏览器关系型数据库的架构、查询引擎与存储引擎设计 导读 Lovefield 是一个用纯 JavaScript 编写、运行在浏关系型数据库数据库前端上一篇Apache SeaTunnel Shade 机制指南包重定位 JAR 的版本约定、依赖消费与发布流程下一篇Semi Design List 列表组件实战指南从基础用法到虚拟滚动、拖拽排序与组合增强创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考