https://github.com/borutainfo/timebase
Flat file database for storage any data as events in timeline and finding it for a given timestamp.
https://github.com/borutainfo/timebase
binary-search database events file-database flat-database php timeline timestamp
Last synced: 19 days ago
JSON representation
Flat file database for storage any data as events in timeline and finding it for a given timestamp.
- Host: GitHub
- URL: https://github.com/borutainfo/timebase
- Owner: borutainfo
- License: mit
- Created: 2021-01-17T16:46:49.000Z (about 5 years ago)
- Default Branch: main
- Last Pushed: 2021-01-30T17:45:44.000Z (about 5 years ago)
- Last Synced: 2025-05-21T04:52:58.707Z (9 months ago)
- Topics: binary-search, database, events, file-database, flat-database, php, timeline, timestamp
- Language: PHP
- Homepage:
- Size: 29.3 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# TimeBase

Flat file database for storage any data as events in timeline and finding it for a given timestamp.
### Table of contents
1. [Description](#description)
2. [Requirements](#requirements)
3. [Installation](#installation)
4. [Usage](#usage)
1. [Quick introduction](#quick-introduction)
2. [Details](#details)
1. [Extra logger in constructor](#extra-logger-in-constructor)
2. [Data types](#data-types)
3. [Setting the storage namespace](#setting-the-storage-namespace)
4. [Inserting data for specific timestamp](#inserting-data-for-specific-timestamp)
5. [Searching data for specific timestamp](#searching-data-for-specific-timestamp)
6. [Getting multiple records with the same timestamp](#getting-multiple-records-with-the-same-timestamp)
7. [Searching strategies](#searching-strategies)
5. [Tests](#tests)
## Description
The data are stored in files, with the possibility of using multi-level namespaces - in this case, the files are stored in subdirectories. Each day is stored in a separate file named `YYYY-MM-DD.tb`.
The data records are searched using a binary search algorithm, so it's quick and doesn't require loading the entire file into memory. Each record is one line in file, in format `{timestamp}/{data}` (`data` is result of `base64_encode(json_encode(...))`). The records are sorted, and you can add multiple records for one timestamp - they are saved and returned in the order they were added.
There are many use cases for such a database, e.g. storing stock exchange data (volumes, price values etc.) for trading strategy backtesting.
## Requirements
Package requires PHP >= 7.3 and ext-json installed.
## Installation
Install the library using Composer. Please read
the [Composer Documentation](https://getcomposer.org/doc/01-basic-usage.md) if you are unfamiliar with Composer or
dependency managers in general.
```shell
composer require boruta/timebase
```
## Usage
### Quick introduction
Creating database instance. First constructor argument is a path where to store database files.
```php
$timebase = new Boruta\Timebase\Timebase(__DIR__ . '/database/');
```
Inserting data (for current timestamp) :
```php
$timebase->insert()->set('test')->execute();
```
Getting last inserted data (last record):
```php
$result = $timebase->search()->execute();
```
You will get array as result, with keys `timestamp` and `value`:
```php
array(2) {
["timestamp"]=>
int(1612022907)
["value"]=>
string(4) "test"
}
```
### Details
#### Extra logger in constructor
You can optionally give the second argument which is a logger object, compatible with `Psr\Log\LoggerInterface`. The application append logs only in case of errors.
```php
$timebase = new Boruta\Timebase\Timebase(__DIR__ . '/database/', $logger);
```
#### Data types
The data can be of any native type, e.g. `int`, `string`, `array`. When searching for data, they will be of the same type.
```php
$timebase->insert()
->set(123) // or ->set('test') or ->set(['test' => 123]) etc.
->execute();
```
#### Setting the storage namespace
You can store your data in different storages on many levels. Please use the method `->storage(array $storage)` to set this.
Examples of inserting data into specific storage:
```php
$timebase->insert()
->storage(['test']) // storage path: __DIR__ . '/database/test/'
->set('test')
->execute();
```
```php
$timebase->insert()
->storage(['level0', 'level1']) // storage path: __DIR__ . '/database/level0/level1/'
->set('test')
->execute();
```
Examples of reading data from specific storage:
```php
$result = $timebase->search()
->storage(['test']) // storage path: __DIR__ . '/database/test/'
->execute();
```
```php
$result = $timebase->search()
->storage(['level0', 'level1']) // storage path: __DIR__ . '/database/level0/level1/'
->execute();
```
#### Inserting data for specific timestamp
To add data for a given timestamp (not the current) use the method `->timestamp(int $timestamp)`. Example:
```php
$timebase->insert()
->timestamp(1612022907)
->set('test')
->execute();
```
#### Searching data for specific timestamp
To find a record for a specific timestamp use the method `->timestamp(int $timestamp)` during search query:
```php
$result = $timebase->search()
->timestamp(1612022907)
->execute();
```
In the default strategy, you will get one record that is closest to the timestamp you entered.
#### Getting multiple records with the same timestamp
If you have more than one record with the same timestamp you can retrieve them using the `->all()` method.
```php
$result = $timebase->search()
->timestamp(1612022907)
->all()
->execute();
```
In the result array there will be an additional key `all` containing all records for given timestamp, in the order in which they were added:
```php
array(3) {
["timestamp"]=>
int(1612012606)
["value"]=>
string(4) "test"
["all"]=>
array(2) {
[0]=>
string(4) "test"
[1]=>
string(4) "test"
}
}
```
#### Searching strategies
**Nearest** (default)
The default strategy returns the record with the nearest timestamp to the given one. Usage (is not necessary as it is the default):
```php
$result = $timebase->search()
->strategy(\Boruta\Timebase\Common\Constant\SearchStrategyConstant::NEAREST)
->timestamp(1612022907)
->execute();
```
If the time distance is the same for two records, you will get the earlier one.
**Exact**
If there is no record for the timestamp you provided, you will get `null` value. There must be a record in the database with exactly the same timestamp.
```php
$result = $timebase->search()
->strategy(\Boruta\Timebase\Common\Constant\SearchStrategyConstant::EXACT)
->timestamp(1612022907)
->execute();
```
**Earlier**
If there is no record for the timestamp you entered, you will get the closest one before that timestamp or `null`.
```php
$result = $timebase->search()
->strategy(\Boruta\Timebase\Common\Constant\SearchStrategyConstant::EARLIER)
->timestamp(1612022907)
->execute();
```
**Later**
If there is no record for the timestamp you entered, you will get the closest one after that timestamp or `null`.
```php
$result = $timebase->search()
->strategy(\Boruta\Timebase\Common\Constant\SearchStrategyConstant::LATER)
->timestamp(1612022907)
->execute();
```
## Tests
To run the tests in the package, execute the following command:
```shell
vendor/bin/phpunit tests
```
After a while you will get the result, example:
```
OK (31 tests, 526577 assertions)
```