平坦文件 Json 数据库

v0.1.13 2023-07-25 08:40 UTC

This package is not auto-updated.

Last update: 2024-09-17 14:25:27 UTC


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();

然后,您需要根据需要使用 addset 将它添加或设置回集合,一旦您用数据填充了数组。

如果您需要使用任何运行时值来设置默认值,则替换 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提供略微更详细的文档,有更清晰的解释和一些更长的示例
  • 测试

维护

Moussa Clarke编写

贡献

请随意提交错误报告、建议和拉取请求。或者,您可以分叉它并创建自己的东西。

许可

MIT