moussaclarke / planar
平坦文件 Json 数据库
Requires
README
一个非常简单的平坦文件 Json 数据库 / 模型
在本说明书中,“文档”和“集合”一词在 MongoDB 的意义上使用。
Planar 是一个非常基础的平坦文件/NoSQL Json 数据库解决方案。
Planar 简单、快速、超级灵活,可能非常脆弱。它适用于小型项目,其中您有一个相对简单的数据结构,不需要成千上万的文档,并且只有少数用户有编辑权限。
它可能不会很好地扩展,没有冲突检测或记录锁定,并且一旦您的集合变得非常大,它可能会变得非常慢。但我已经在生产应用程序中使用了它,有数百个文档,至今没有遇到任何问题。
Planar 会根据需要动态创建 Json 集合,所有内容都会被 Json 编码并存储在平坦文件中。它类似于 ORM,尽管这个术语几乎无关紧要,因为所有这些都是 Json,但您可以在“模型”对象上执行 CRUD 和简单查询。
它使用差异来备份每个更改,从而使撤销变得可能。
免责声明
它仍然处于相当初级的 alpha 版本,可能会随时崩溃,我可能会在不警告的情况下进行向后不兼容的更改。不要将其用于任何过于关键的业务。已警告。
安装
composer require moussaclarke\planar
使用
实例化
在最简单的情况下,您只需扩展该类以创建您的模型/集合。它将使用类名(复数在这里是合适的)作为 Json 集合名称。
use MoussaClarke\Planar;
class Widgets extends Planar
{
}
然后,您可以通过传递数据文件夹位置来实例化。Json 和备份差异文件将存储在您指定的文件夹中。如果 Json 文件尚不存在,则将其创建。
$widgets = new Widgets('path/to/data/folder');
您也可以通过覆盖类上的 datafolder 属性来设置数据文件夹位置。
protected $datafolder='path/to/data/folder';
然后,您只需执行以下操作即可实例化
$widgets = new Widgets;
您可以将数据文件夹设置为基模型类,例如,具体模型扩展的基模型。
或者,如果您需要稍微松散耦合一些,您也可以在不扩展 Planar 类的情况下注入数据文件夹和集合名称。
$widgets = new Planar('path/to/data/folder', 'Widgets');
架构
您可以为文档添加架构,如果您喜欢 - Planar 不会执行任何操作来强制执行它,并且每个文档实际上可能具有完全不同的元素 - 但在您的应用程序的其他地方,如果您试图保持更严格的数据模型结构,它可能很有用,例如作为配置信息的某种类型。为此,只需在模型类顶部覆盖 $schema
属性即可。
protected $schema = [
'name' => ''
'price' => '',
'weight' => '',
'subwidgets' => [],
];
您的初始属性默认值通常是空字符串或数组,但您也可以指定默认值。然后,您可以像这样获取您的架构
$schema = $widgets->getSchema();
然后,您需要根据需要使用 add
或 set
将它添加或设置回集合,一旦您用数据填充了数组。
如果您需要使用任何运行时值来设置默认值,则替换 getSchema
方法。
public function getSchema()
{
return [
'name' => ''
'price' => '',
'weight' => '',
'subwidgets' => [],
'invoicedate' => date ('Y-m-d')
];
}
创建 & 更新
您可以使用 add
创建文档。只需传递一个数据数组(它将被简单地 Json 编码),它将返回新文档的唯一 ID。
$data = [
'name' => 'foobar',
'price' => 5,
'weight' => 10,
'subwidget' => ['foo' => 'bar', 'bar' => 'foo']
];
$id = $widgets->add($data);
您不需要担心添加唯一ID或时间戳字段,这些将自动创建和更新。_id
只是一个uniqid()
,而_created
和_modified
是Unix时间戳。这三个属性名,都以前缀_
开头,因此是保留的,所以尽量不要在您的数据/模式中使用这些。
如果您知道ID,您可以使用set
替换整个文档。您也可以使用此方法创建具有特定ID的文档,尽管Planar在覆盖任何内容时不会警告您。
$widgets->set('57d1d2fc97aee', $data);
查找 & 搜索
Planar有多种查找和搜索记录的方式,但并不真正支持任何特别复杂的查询。find
返回一个文档数组,其中命名属性具有特定值。
$result = $widgets->find('price', 5);
first
返回第一个具有特定值的命名属性的文档。
$result = $widgets->first('_id', '57d1d2fc97aee');
all
返回整个集合作为数组,因此您可以在其上执行更复杂的查询。
$result = $widgets->all();
您还可以通过传递一个属性名来按升序对all
结果进行排序。
$result = $widgets->all('price');
search
允许您在整个集合中搜索一个词或短语。它返回一个文档数组,其中任何属性都包含该值,并且不区分大小写。
$result = $widgets->search('foo');
删除、撤销 & 恢复
如果您知道ID,您可以delete
一个文档。
$widgets->delete('57d1d2fc97aee');
只要集合是持久的,您就可以轻松检索到最后一个保存点时的文档的先前版本,例如,执行撤销。
// get the previous version
$previous = $widgets->history('57d1d2fc97aee');
// undo i.e. set document to previous version
$widgets->set('57d1d2fc97aee', $previous);
您可以通过指定要回退的步数来检索旧版本。
// get the version of the document three saves ago
$historical = $widgets->history('57d1d2fc97aee', 3);
虽然您可以使用history
检索已删除的文档,但您不能在已删除的情况下set
文档。但是,您可以将已删除的文档restore
回其原始ID。
// delete the document
$widgets->delete('57d1d2fc97aee');
// and undelete it
$widgets->restore('57d1d2fc97aee');
失败
上述大多数方法在失败时将返回false
,因此您可以根据您的调用是否成功进行检查。
if ($widgets->delete('57d1d2fc97aee')) {
echo 'Document succesfully deleted';
} else {
echo 'Document not found';
}
只有add
方法从不返回false
。如前所述,它基本上会json_encode
您提供的任何数组,所以它不会真正“失败”,除非您不发送数组。这有其自身的风险,所以请确保您提供的数据不是太奇怪!
持久性
您可能有时想要非持久集合,例如,您可能想要实例化一个嵌入式模型来构建您的UI,但这对于数据在其自己的集合中持久化来说没有意义,因为最终它被保存到父模型/集合中。对于此用例,只需覆盖类的$persists
属性,它将每天垃圾收集一次。
protected $persists = false;
待办事项
检索历史状态/撤销恢复删除- 错误/异常
- 更细粒度的set方法,即只设置一个属性而不是整个文档。
- 一些更好的查询/搜索选项,例如模糊搜索/正则表达式
文档注释- 使用Daux.io提供略微更详细的文档,有更清晰的解释和一些更长的示例
- 测试
维护
贡献
请随意提交错误报告、建议和拉取请求。或者,您可以分叉它并创建自己的东西。
许可
MIT