Vendoring deprecated composer libs
This commit is contained in:
672
libs/picodb/README.md
Normal file
672
libs/picodb/README.md
Normal file
@@ -0,0 +1,672 @@
|
||||
PicoDb
|
||||
======
|
||||
|
||||
PicoDb is a minimalist database query builder for PHP.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
- Easy to use, easy to hack, fast and very lightweight
|
||||
- Supported drivers: Sqlite, Mssql, Mysql, Postgresql
|
||||
- Requires only PDO
|
||||
- Use prepared statements
|
||||
- Handle schema migrations
|
||||
- Fully unit tested on PHP 5.3, 5.4, 5.5, 5.6 and 7.0
|
||||
- License: MIT
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- PHP >= 5.3
|
||||
- PDO extension
|
||||
- Sqlite, Mssql, Mysql or Postgresql
|
||||
|
||||
Author
|
||||
------
|
||||
|
||||
Frédéric Guillot
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
composer require fguillot/picodb @stable
|
||||
```
|
||||
|
||||
### Database connection
|
||||
|
||||
#### Sqlite:
|
||||
|
||||
```php
|
||||
use PicoDb\Database;
|
||||
|
||||
// Sqlite driver
|
||||
$db = new Database(['driver' => 'sqlite', 'filename' => ':memory:']);
|
||||
```
|
||||
|
||||
The Sqlite driver enable foreign keys by default.
|
||||
|
||||
#### Microsoft SQL server:
|
||||
|
||||
```php
|
||||
// Optional attributes:
|
||||
// "schema_table" (the default table name is "schema_version")
|
||||
|
||||
$db = new Database([
|
||||
'driver' => 'mssql',
|
||||
'hostname' => 'localhost',
|
||||
'username' => 'root',
|
||||
'password' => '',
|
||||
'database' => 'my_db_name',
|
||||
]);
|
||||
```
|
||||
|
||||
Optional attributes:
|
||||
|
||||
- schema_table
|
||||
|
||||
#### Mysql:
|
||||
|
||||
```php
|
||||
$db = new Database([
|
||||
'driver' => 'mysql',
|
||||
'hostname' => 'localhost',
|
||||
'username' => 'root',
|
||||
'password' => '',
|
||||
'database' => 'my_db_name',
|
||||
'ssl_key' => '/path/to/client-key.pem',
|
||||
'ssl_cert' => '/path/to/client-cert.pem',
|
||||
'ssl_ca' => '/path/to/ca-cert.pem',
|
||||
]);
|
||||
```
|
||||
|
||||
Optional attributes:
|
||||
|
||||
- charset
|
||||
- schema_table
|
||||
- port
|
||||
- ssl_key
|
||||
- ssl_cert
|
||||
- ssl_key
|
||||
|
||||
#### Postgres:
|
||||
|
||||
```php
|
||||
$db = new Database([
|
||||
'driver' => 'postgres',
|
||||
'hostname' => 'localhost',
|
||||
'username' => 'root',
|
||||
'password' => '',
|
||||
'database' => 'my_db_name',
|
||||
]);
|
||||
```
|
||||
|
||||
Optional attributes:
|
||||
|
||||
- port
|
||||
- schema_table
|
||||
|
||||
#### Connecting from an environment variable:
|
||||
|
||||
Let's say you have defined an environment variable:
|
||||
|
||||
```bash
|
||||
export DATABASE_URL=postgres://user:pass@hostname:6212/db
|
||||
```
|
||||
|
||||
PicoDb can parse automatically this URL for you:
|
||||
|
||||
```php
|
||||
use PicoDb\UrlParser;
|
||||
use PicoDb\Database;
|
||||
|
||||
$db = new Database(UrlParser::getInstance()->getSettings());
|
||||
```
|
||||
|
||||
#### Connecting from a URL
|
||||
|
||||
```php
|
||||
use PicoDb\UrlParser;
|
||||
use PicoDb\Database;
|
||||
|
||||
$db = new Database(UrlParser::getInstance()->getSettings('postgres://user:pass@hostname:6212/db'));
|
||||
```
|
||||
|
||||
### Execute any SQL query
|
||||
|
||||
```php
|
||||
$db->execute('CREATE TABLE mytable (column1 TEXT)');
|
||||
```
|
||||
|
||||
- Returns a `PDOStatement` if successful
|
||||
- Returns `false` if there is a duplicate key error
|
||||
- Throws a `SQLException` for other errors
|
||||
|
||||
### Insertion
|
||||
|
||||
```php
|
||||
$db->table('mytable')->save(['column1' => 'test']);
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```php
|
||||
$db->table('mytable')->insert(['column1' => 'test']);
|
||||
```
|
||||
|
||||
### Fetch last inserted id
|
||||
|
||||
```php
|
||||
$db->getLastId();
|
||||
```
|
||||
|
||||
### Transactions
|
||||
|
||||
```php
|
||||
$db->transaction(function ($db) {
|
||||
$db->table('mytable')->save(['column1' => 'foo']);
|
||||
$db->table('mytable')->save(['column1' => 'bar']);
|
||||
});
|
||||
```
|
||||
|
||||
- Returns `true` if the callback returns null
|
||||
- Returns the callback return value otherwise
|
||||
- Throws an SQLException if something is wrong
|
||||
|
||||
or
|
||||
|
||||
```php
|
||||
$db->startTransaction();
|
||||
// Do something...
|
||||
$db->closeTransaction();
|
||||
|
||||
// Rollback
|
||||
$db->cancelTransaction();
|
||||
```
|
||||
|
||||
### Fetch all data
|
||||
|
||||
```php
|
||||
$records = $db->table('mytable')->findAll();
|
||||
|
||||
foreach ($records as $record) {
|
||||
var_dump($record['column1']);
|
||||
}
|
||||
```
|
||||
|
||||
### Updates
|
||||
|
||||
```php
|
||||
$db->table('mytable')->eq('id', 1)->save(['column1' => 'hey']);
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```php
|
||||
$db->table('mytable')->eq('id', 1)->update(['column1' => 'hey']);
|
||||
```
|
||||
|
||||
### Remove records
|
||||
|
||||
```php
|
||||
$db->table('mytable')->lt('column1', 10)->remove();
|
||||
```
|
||||
|
||||
### Sorting
|
||||
|
||||
```php
|
||||
$db->table('mytable')->asc('column1')->findAll();
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```php
|
||||
$db->table('mytable')->desc('column1')->findAll();
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```php
|
||||
$db->table('mytable')->orderBy('column1', 'ASC')->findAll();
|
||||
```
|
||||
|
||||
Multiple sorting:
|
||||
|
||||
```php
|
||||
$db->table('mytable')->asc('column1')->desc('column2')->findAll();
|
||||
```
|
||||
|
||||
### Limit and offset
|
||||
|
||||
```php
|
||||
$db->table('mytable')->limit(10)->offset(5)->findAll();
|
||||
```
|
||||
|
||||
### Fetch only some columns
|
||||
|
||||
```php
|
||||
$db->table('mytable')->columns('column1', 'column2')->findAll();
|
||||
```
|
||||
|
||||
### Fetch only one column
|
||||
|
||||
Many rows:
|
||||
|
||||
```php
|
||||
$db->table('mytable')->findAllByColumn('column1');
|
||||
```
|
||||
|
||||
One row:
|
||||
|
||||
```php
|
||||
$db->table('mytable')->findOneColumn('column1');
|
||||
```
|
||||
|
||||
### Custom select
|
||||
|
||||
```php
|
||||
$db->table('mytable')->select(1)->eq('id', 42)->findOne();
|
||||
```
|
||||
|
||||
### Distinct
|
||||
|
||||
```php
|
||||
$db->table('mytable')->distinct('columnA')->findOne();
|
||||
```
|
||||
|
||||
### Group by
|
||||
|
||||
```php
|
||||
$db->table('mytable')->groupBy('columnA')->findAll();
|
||||
```
|
||||
|
||||
### Count
|
||||
|
||||
```php
|
||||
$db->table('mytable')->count();
|
||||
```
|
||||
|
||||
### Sum
|
||||
|
||||
```php
|
||||
$db->table('mytable')->sum('columnB');
|
||||
```
|
||||
|
||||
### Sum column values during update
|
||||
|
||||
Add the value 42 to the existing value of the column "mycolumn":
|
||||
|
||||
```php
|
||||
$db->table('mytable')->sumColumn('mycolumn', 42)->update();
|
||||
```
|
||||
|
||||
### Increment column
|
||||
|
||||
Increment a column value in a single query:
|
||||
|
||||
```php
|
||||
$db->table('mytable')->eq('another_column', 42)->increment('my_column', 2);
|
||||
```
|
||||
|
||||
### Decrement column
|
||||
|
||||
Decrement a column value in a single query:
|
||||
|
||||
```php
|
||||
$db->table('mytable')->eq('another_column', 42)->decrement('my_column', 1);
|
||||
```
|
||||
|
||||
### Exists
|
||||
|
||||
Returns true if a record exists otherwise false.
|
||||
|
||||
```php
|
||||
$db->table('mytable')->eq('column1', 12)->exists();
|
||||
```
|
||||
|
||||
### Left joins
|
||||
|
||||
```php
|
||||
// SELECT * FROM mytable LEFT JOIN my_other_table AS t1 ON t1.id=mytable.foreign_key
|
||||
$db->table('mytable')->left('my_other_table', 't1', 'id', 'mytable', 'foreign_key')->findAll();
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```php
|
||||
// SELECT * FROM mytable LEFT JOIN my_other_table ON my_other_table.id=mytable.foreign_key
|
||||
$db->table('mytable')->join('my_other_table', 'id', 'foreign_key')->findAll();
|
||||
```
|
||||
|
||||
### Equals condition
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->eq('column1', 'hey')
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### IN condition
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->in('column1', ['hey', 'bla'])
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### IN condition with subquery
|
||||
|
||||
```php
|
||||
$subquery = $db->table('another_table')->columns('column2')->eq('column3', 'value3');
|
||||
|
||||
$db->table('mytable')
|
||||
->columns('column_5')
|
||||
->inSubquery('column1', $subquery)
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### Like condition
|
||||
|
||||
Case-sensitive (only Mysql and Postgres):
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->like('column1', '%Foo%')
|
||||
->findAll();
|
||||
```
|
||||
|
||||
Not case-sensitive:
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->ilike('column1', '%foo%')
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### Lower than condition
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->lt('column1', 2)
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### Lower than or equal condition
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->lte('column1', 2)
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### Greater than condition
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->gt('column1', 3)
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### Greater than or equal condition
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->gte('column1', 3)
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### IS NULL condition
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->isNull('column1')
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### IS NOT NULL condition
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->notNull('column1')
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### Multiple conditions
|
||||
|
||||
Add conditions are joined by a `AND`.
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->like('column2', '%mytable')
|
||||
->gte('column1', 3)
|
||||
->findAll();
|
||||
```
|
||||
|
||||
How to make a OR condition:
|
||||
|
||||
```php
|
||||
$db->table('mytable')
|
||||
->beginOr()
|
||||
->like('column2', '%mytable')
|
||||
->gte('column1', 3)
|
||||
->closeOr()
|
||||
->eq('column5', 'titi')
|
||||
->findAll();
|
||||
```
|
||||
|
||||
### Debugging
|
||||
|
||||
Log generated queries:
|
||||
|
||||
```php
|
||||
$db->getStatementHandler()->withLogging();
|
||||
```
|
||||
|
||||
Mesure each query time:
|
||||
|
||||
```php
|
||||
$db->getStatementHandler()->withStopWatch();
|
||||
```
|
||||
|
||||
Get the number of queries executed:
|
||||
|
||||
```php
|
||||
echo $db->getStatementHandler()->getNbQueries();
|
||||
```
|
||||
|
||||
Get log messages:
|
||||
|
||||
```php
|
||||
print_r($db->getLogMessages());
|
||||
```
|
||||
|
||||
### Large objects (LOBs)
|
||||
|
||||
Insert a file:
|
||||
|
||||
```php
|
||||
$db->largeObject('my_table')->insertFromFile('blobColumn', '/path/to/file', array('id' => 'something'));
|
||||
```
|
||||
|
||||
Insert from a stream:
|
||||
|
||||
```php
|
||||
$db->largeObject('my_table')->insertFromStream('blobColumn', $fd, array('id' => 'something'));
|
||||
```
|
||||
|
||||
Fetch a large object as a stream (Postgres only):
|
||||
|
||||
```php
|
||||
$fd = $db->largeObject('my_table')->eq('id', 'something')->findOneColumnAsStream('blobColumn');
|
||||
```
|
||||
|
||||
Fetch a large object as a string:
|
||||
|
||||
```php
|
||||
echo $db->largeObject('my_table')->eq('id', 'something')->findOneColumnAsString('blobColumn');
|
||||
```
|
||||
|
||||
Drivers:
|
||||
|
||||
- Postgres
|
||||
- Column type: `bytea`
|
||||
- Sqlite and Mysql
|
||||
- Column type: `BLOB`
|
||||
- PDO do no not supports the stream feature (returns a string instead)
|
||||
|
||||
### Hashtable (key/value store)
|
||||
|
||||
How to use a table as a key/value store:
|
||||
|
||||
```php
|
||||
$db->execute(
|
||||
'CREATE TABLE mytable (
|
||||
column1 TEXT NOT NULL UNIQUE,
|
||||
column2 TEXT default NULL
|
||||
)'
|
||||
);
|
||||
|
||||
$db->table('mytable')->insert(['column1' => 'option1', 'column2' => 'value1']);
|
||||
```
|
||||
|
||||
Add/Replace some values:
|
||||
|
||||
```php
|
||||
$db->hashtable('mytable')
|
||||
->columnKey('column1')
|
||||
->columnValue('column2')
|
||||
->put(['option1' => 'new value', 'option2' => 'value2']));
|
||||
```
|
||||
|
||||
Get all values:
|
||||
|
||||
```php
|
||||
$result = $db->hashtable('mytable')->columnKey('column1')->columnValue('column2')->get();
|
||||
print_r($result);
|
||||
|
||||
Array
|
||||
(
|
||||
[option2] => value2
|
||||
[option1] => new value
|
||||
)
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```php
|
||||
$result = $db->hashtable('mytable')->getAll('column1', 'column2');
|
||||
```
|
||||
|
||||
Get a specific value:
|
||||
|
||||
```php
|
||||
$db->hashtable('mytable')
|
||||
->columnKey('column1')
|
||||
->columnValue('column2')
|
||||
->put(['option3' => 'value3']);
|
||||
|
||||
$result = $db->hashtable('mytable')
|
||||
->columnKey('column1')
|
||||
->columnValue('column2')
|
||||
->get('option1', 'option3');
|
||||
|
||||
print_r($result);
|
||||
|
||||
Array
|
||||
(
|
||||
[option1] => new value
|
||||
[option3] => value3
|
||||
)
|
||||
```
|
||||
|
||||
### Schema migrations
|
||||
|
||||
#### Define a migration
|
||||
|
||||
- Migrations are defined in simple functions inside a namespace named "Schema".
|
||||
- An instance of PDO is passed to first argument of the function.
|
||||
- Function names has the version number at the end.
|
||||
|
||||
Example:
|
||||
|
||||
```php
|
||||
namespace Schema;
|
||||
|
||||
function version_1($pdo)
|
||||
{
|
||||
$pdo->exec('
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT UNIQUE,
|
||||
email TEXT UNIQUE,
|
||||
password TEXT
|
||||
)
|
||||
');
|
||||
}
|
||||
|
||||
|
||||
function version_2($pdo)
|
||||
{
|
||||
$pdo->exec('
|
||||
CREATE TABLE tags (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT UNIQUE
|
||||
)
|
||||
');
|
||||
}
|
||||
```
|
||||
|
||||
#### Run schema update automatically
|
||||
|
||||
- The method `check()` execute all migrations until the version specified
|
||||
- If an error occurs, the transaction is rollbacked
|
||||
- Foreign keys checks are disabled if possible during the migration
|
||||
|
||||
Example:
|
||||
|
||||
```php
|
||||
$last_schema_version = 5;
|
||||
|
||||
$db = new PicoDb\Database(array(
|
||||
'driver' => 'sqlite',
|
||||
'filename' => '/tmp/mydb.sqlite'
|
||||
));
|
||||
|
||||
if ($db->schema()->check($last_schema_version)) {
|
||||
|
||||
// Do something...
|
||||
}
|
||||
else {
|
||||
|
||||
die('Unable to migrate database schema.');
|
||||
}
|
||||
```
|
||||
|
||||
### Use a singleton to handle database instances
|
||||
|
||||
Setup a new instance:
|
||||
|
||||
```php
|
||||
PicoDb\Database::setInstance('myinstance', function() {
|
||||
|
||||
$db = new PicoDb\Database(array(
|
||||
'driver' => 'sqlite',
|
||||
'filename' => DB_FILENAME
|
||||
));
|
||||
|
||||
if ($db->schema()->check(DB_VERSION)) {
|
||||
return $db;
|
||||
}
|
||||
else {
|
||||
die('Unable to migrate database schema.');
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Get this instance anywhere in your code:
|
||||
|
||||
```php
|
||||
PicoDb\Database::getInstance('myinstance')->table(...)
|
||||
```
|
||||
Reference in New Issue
Block a user