- Notifications
You must be signed in to change notification settings - Fork0
Flat file database for storage any data as events in timeline and finding it for a given timestamp.
License
borutainfo/timebase
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Flat file database for storage any data as events in timeline and finding it for a given timestamp.
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 namedYYYY-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 ofbase64_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.
Package requires PHP >= 7.3 and ext-json installed.
Install the library using Composer. Please readtheComposer Documentation if you are unfamiliar with Composer ordependency managers in general.
composer require boruta/timebase
Creating database instance. First constructor argument is a path where to store database files.
$timebase =newBoruta\Timebase\Timebase(__DIR__ .'/database/');
Inserting data (for current timestamp) :
$timebase->insert()->set('test')->execute();
Getting last inserted data (last record):
$result =$timebase->search()->execute();
You will get array as result, with keystimestamp
andvalue
:
array(2) { ["timestamp"]=> int(1612022907) ["value"]=> string(4)"test"}
You can optionally give the second argument which is a logger object, compatible withPsr\Log\LoggerInterface
. The application append logs only in case of errors.
$timebase =newBoruta\Timebase\Timebase(__DIR__ .'/database/',$logger);
The data can be of any native type, e.g.int
,string
,array
. When searching for data, they will be of the same type.
$timebase->insert() ->set(123)// or ->set('test') or ->set(['test' => 123]) etc. ->execute();
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:
$timebase->insert() ->storage(['test'])// storage path: __DIR__ . '/database/test/' ->set('test') ->execute();
$timebase->insert() ->storage(['level0','level1'])// storage path: __DIR__ . '/database/level0/level1/' ->set('test') ->execute();
Examples of reading data from specific storage:
$result =$timebase->search() ->storage(['test'])// storage path: __DIR__ . '/database/test/' ->execute();
$result =$timebase->search() ->storage(['level0','level1'])// storage path: __DIR__ . '/database/level0/level1/' ->execute();
To add data for a given timestamp (not the current) use the method->timestamp(int $timestamp)
. Example:
$timebase->insert() ->timestamp(1612022907) ->set('test') ->execute();
To find a record for a specific timestamp use the method->timestamp(int $timestamp)
during search query:
$result =$timebase->search() ->timestamp(1612022907) ->execute();
In the default strategy, you will get one record that is closest to the timestamp you entered.
If you have more than one record with the same timestamp you can retrieve them using the->all()
method.
$result =$timebase->search() ->timestamp(1612022907) ->all() ->execute();
In the result array there will be an additional keyall
containing all records for given timestamp, in the order in which they were added:
array(3) { ["timestamp"]=> int(1612012606) ["value"]=> string(4)"test" ["all"]=>array(2) { [0]=> string(4)"test" [1]=> string(4)"test" }}
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):
$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 getnull
value. There must be a record in the database with exactly the same timestamp.
$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 ornull
.
$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 ornull
.
$result =$timebase->search() ->strategy(\Boruta\Timebase\Common\Constant\SearchStrategyConstant::LATER) ->timestamp(1612022907) ->execute();
To run the tests in the package, execute the following command:
vendor/bin/phpunit tests
After a while you will get the result, example:
OK (31 tests, 526577 assertions)
About
Flat file database for storage any data as events in timeline and finding it for a given timestamp.