{"id":43121163,"url":"https://github.com/etigerstudio/recordflow","last_synced_at":"2026-01-31T19:36:51.077Z","repository":{"id":57349323,"uuid":"138847168","full_name":"etigerstudio/recordflow","owner":"etigerstudio","description":"Oh my! Such a delightful NoSQL database built on Node.js.","archived":false,"fork":false,"pushed_at":"2020-02-17T02:15:30.000Z","size":137,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-06T09:16:36.520Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/etigerstudio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-06-27T07:42:06.000Z","updated_at":"2020-02-17T02:15:33.000Z","dependencies_parsed_at":"2022-08-29T18:41:43.238Z","dependency_job_id":null,"html_url":"https://github.com/etigerstudio/recordflow","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/etigerstudio/recordflow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etigerstudio%2Frecordflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etigerstudio%2Frecordflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etigerstudio%2Frecordflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etigerstudio%2Frecordflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/etigerstudio","download_url":"https://codeload.github.com/etigerstudio/recordflow/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/etigerstudio%2Frecordflow/sbom","scorecard":{"id":384295,"data":{"date":"2025-08-11","repo":{"name":"github.com/etigerstudio/recordflow","commit":"e4443482f465db5174623b17fef87d561c39983b"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/17 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}}]},"last_synced_at":"2025-08-18T16:14:20.168Z","repository_id":57349323,"created_at":"2025-08-18T16:14:20.168Z","updated_at":"2025-08-18T16:14:20.168Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28951659,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T18:30:42.805Z","status":"ssl_error","status_checked_at":"2026-01-31T18:30:19.593Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-31T19:36:51.022Z","updated_at":"2026-01-31T19:36:51.072Z","avatar_url":"https://github.com/etigerstudio.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Hero](images/hero.png)\n\n## 设计\n\n### 概念设计\n\nRecordFlow，即记录流，是一个愉快的NoSQL数据库。（以下也称RecordFlow为RF）\n\nRecordFlow主要的目标是优雅而高效的语法（见“[语法设计](#语法设计)”）、轻量而便捷的分发（见“[安装](#安装)”）。RF由概念、设计、实现到诞生的每一个阶段都围绕这个目标而展开。\n\nRecordFlow将记录作为数据基本单位，记录以流的形式逐条流入，在RF中逐条处理。所有RF的操作的中心都是记录。\n\n### 词法设计\n\nRF的数据单位分为三种。\n\n#### 记录项\n\n记录项（record_item）是最小的数据单位，是一个键值对。其概念类似关系数据库的一个字段。如下：\n\n```\nname: value\n```\n\n`name`为该标识该记录项的名称，`value`为该记录项所包含的值，冒号隔开。\n\n#### 记录\n\n一条记录（record_entity）由一个或多个记录项组成，是一个字典。其概念类似关系数据库的一条记录。的如下：\n\n```\n{record_item_1, ..., record_item_n}\n```\n\n`record_item_n`为n个属于该记录的记录项，记录项间使用逗号隔开。\n\n例如：\n\n```\n{price: 650}\n{price: 1000, name: 'Odyssey', model: 'AN938P'}\n```\n\n#### 记录集合\n\n记录集合（collection_entity）是最大的数据单位，是由零个或多个记录组成的集合。其概念类似关系数据库的一张表。记录集合用唯一集合名所标识，例如：\n\n```\ncars\ndefault\n```\n\n### 语法设计\n\nRF共有四种操作，覆盖到增删改查（CRUD）的每一方面，可以在一次操作中实现关系数据库中除连接查询之外相对应的大部分功能。\n\nRF共有两大操作符：\n\n1. `-\u003e`  即右箭头，表示数据的查询与删除操作。\n2. `\u003c-`  即左箭头，表示数据的插入与更新操作。\n\n#### 插入\n\n插入（insert）操作向一个记录集合中插入一条记录。如下：\n\n\n```\ncollection_entity \u003c- record_entity\n```\n\n例如：\n\n```\ndefault \u003c- {price: 650}\ndefault \u003c- {price: 1000, name: 'Odyssey', model: 'AN938P'}\n```\n\n#### 查询\n\n查询（query）操作返回一个记录集合中所有满足指定条件的记录集。\n\n其中，记录集（record_map）是记录集合的子集，映射来自记录集合的零条或多条记录。\n查询操作语法如下：\n\n```\ncollection_entity -\u003e record_filter_entity\n```\n\n其中记录过滤器（record_filter_entity）用来指定查询的条件，常用的比较过滤器有：\n\n```\n{name = value}\n{name \u003c value}\n{name \u003e value}\n```\n\n查询操作示例：\n\n```\ndefault -\u003e {name = 'Odyssey'}\ndefault -\u003e {price \u003e 700}\n```\n\n#### 更新\n\n更新（update）操作将从记录集合中查询出的记录集与给定记录归并更新。如下：\n\n```\ncollection_entity -\u003e record_filter_entity \u003c- record_entity\n```\n\n该操作左部与查询操作一致，生成一个记录集。该记录集中的每条原记录与右部新记录（record_entity）归并（merge），而更新记录项。\n\n归并的具体机制如下：\n\n对于新记录的每个记录项\n\n- 若原记录含有同名记录项，则将原记录项的值更新为新记录项\n- 若原记录不含同名记录项，则将新记录项插入原记录。\n\n更新操作示例：\n\n```\ndefault -\u003e {price \u003e 600} \u003c- {quality: 'high'}\ndefault -\u003e {name = 'Odyssey'} \u003c- {price: 700}\n```\n\n#### 删除\n\n删除（drop）操作将从记录集合中查询出的记录集删除。如下：\n\n```\ncollection_entity -\u003e record_filter_entity -\u003e\n```\n\n该操作左部与查询操作一致，生成一个记录集。右部右箭头后内容为空，表示删除。例如：\n\n```\ndefault -\u003e {model = 'A1238P'} -\u003e\ndefault -\u003e {price \u003c 700} -\u003e\n```\n\n## 实现\n\nRF采用 `前端`、`解释器` 、 `后端` 分立的架构：![Architecture](images/architecture.png)\n\nRF整体以 Node.js 为开发平台，JavaScript为开发语言实现。\n\nRF解释器使用Jison作为词法、语法、语义分析器。Jison是基于JavaScript实现的Flex（Lex开源实现）与Bison（Yacc开源实现）。\n\n### 前端\n\nRF前端是一个命令行程序，有 `直接` 和 `REPL` （Read-Eval-Print-Loop，即时交互）两种工作模式。前端负责与用户交互、从文件系统或命令行读入操作流，并逐条递交至解释器。\n\n#### 直接模式\n\nRF在直接模式中读取一份存有所有操作序列的文本文件（推荐使用 `.rf` 做为扩展名），逐条解析，输出相关的结果提示，之后退出。\n\n直接模式的命令格式为：\n\n```\nrecordflow file_name\n```\n\n例如：\n\n```\nrecordflow test.rf\n```\n\n#### REPL\n\n不带参数，直接运行RF即可进入即时交互模式：\n\n```\nrecordflow\n\u003c- recordflow 0.1.1 -\u003e\n\n:\n```\n\n交互模式下，在 `:` 提示符之后逐条输入操作，回车即可立即执行并返回结果信息：\n\n```\n: default\nrf.collection: 0 records in collection 'default'.\n\n: default \u003c- {name: 'Max', grade: 88}\nrf.record.insert: record with 2 items inserted.\n{name: 'Max', grade: 88}\n\n: default -\u003e {grade \u003e 40}\nrf.record_set: 1 records in record_set.\n[{name: 'Max', grade: 88, _id: ...c72c}]\n\n: default -\u003e\nrf.collection.drop_all: 1 records dropped.\n```\n\n按下 `Ctrl-C` 即可退出RF。\n\n### 后端\n\n后端由自主开发的记录仓库（warehouse）所实现。\n\n#### 自动持久化\n\n在每次RF执行操作前前自动读入所有记录集合，退出之前自动向工作目录写入所有记录集合。\n\n其中写入的具体实现是向 `rf_rec` 目录写入以JSON形式序列化的记录集合。\n\n#### 信息反馈\n\n后端在处理完记录操作之后，将结果信息以文本的形式反馈至前端。\n\n#### 记录操纵接口\n\nRF的记录仓库拥有独立的操纵接口（API），与前端和解释器相解耦。开发者可以在 JS 中直接调用此接口进行 NoSQL 数据库开发。例如：\n\n```javascript\nconst warehouse = require('../warehouse/warehouse');\nconst filter = require('../warehouse/filter');\nconst {record, record_item} = require('../warehouse/record');\n\nwarehouse.load();\nlet rec = record.build();\nrec.appendItems([new record_item('price', 800),new record_item('model', 'A1238P')]);\nwarehouse.collection('default').append(rec);\nlet all_rec = warehouse.collection('default').record(filter.all());\nconsole.log(all_rec.toString());\nlet gt_rec = warehouse.collection('default').record(filter.gt('price', 600));\nwarehouse.save();\n```\n\n### 安装\n\nRF的一个基本出发点就是易分发性。在安装 Node.js 的、接入互联网的机器上，只需运行以下命令，即可在5秒内完成安装：\n\n```\nnpm i -g recordflow\n```\n\n安装完成后，在任意位置，即可输入 `recordflow ` 命令进入REPL测试RF：\n\n```\nrecordflow\n\u003c- recordflow 0.1.1 -\u003e\n\n:\n```\n\n## 展望\n\n现阶段RecordFlow所实现的功能跟顶级 No-SQL 或 RDBMS 相比还非常有限，架构组织存在不太合理的地方，以后的开发将注重以下几个方面：\n\n### 信息系统重构\n\n目前记录操作的信息反馈系统，内聚偏低、耦合偏高，实现时使用了一些类的私有函数，难于扩展。需要一次完整的重构来解决这些遗留问题。\n\n### 过滤器完善\n\n实现过滤器组，增加逻辑过滤器，增加更多函数过滤器，实现项名变换器。例如：\n\n```\ndefault -\u003e {price \u003e 600, quality} -\u003e {weight \u003e 3000}\nStudents -\u003e {age \u003e= 18 \u0026 sex = 0 | gpa \u003c 3.5} -\u003e {name}\ndefault -\u003e {:last} -\u003e {name}\n```\n\n### 多记录插入\n\n同时插入多个记录：\n\n```\nStudents \u003c- [{name: 'Max', id: 1}, \n\t\t\t {name: 'Chloe', id: 2},\n\t\t\t {name: 'Rachel', id: 3},\n\t\t\t {name: 'Warren', id: 4}]\n```\n\n### 操作嵌套\n\n允许动态记录嵌套，进一步提高单句操作表达能力：\n\n```\n(Students -\u003e {name = 'Max'}) \u003c- (Students -\u003e {name = 'Chloe'} -\u003e {gpa})\nStudents -\u003e {grade \u003e= (Students -\u003e {grade} -\u003e {:average}) }\n```\n\n\u003e Copyright 2018 E-Tiger Studio","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fetigerstudio%2Frecordflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fetigerstudio%2Frecordflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fetigerstudio%2Frecordflow/lists"}