miniflux-legacy/vendor/fguillot/picodb
Frederic Guillot 154abcd57b Update vendor
2015-06-21 09:56:36 -04:00
..
lib/PicoDb Update vendor 2015-06-21 09:56:36 -04:00
.gitignore
composer.json Update vendor 2015-06-21 09:56:36 -04:00
LICENSE Update vendor 2015-06-21 09:56:36 -04:00
README.md Update vendor 2015-06-21 09:56:36 -04:00

PicoDb

PicoDb is a minimalist database query builder for PHP. It's not an ORM.

Features

  • Easy to use, easy to hack, fast and very lightweight
  • Supported drivers: Sqlite, Mysql, Postgresql
  • Requires only PDO
  • Use prepared statements
  • Handle schema versions (migrations)
  • License: MIT

Requirements

  • PHP >= 5.3
  • PDO
  • A database: Sqlite, Mysql or Postgresql

Documentation

Installation

composer require fguillot/picodb @stable

Connect to your database

use PicoDb\Database;

// Sqlite driver
$db = new Database(['driver' => 'sqlite', 'filename' => ':memory:']);

// Mysql driver
// Optional options: "schema_table" (the default table name is "schema_version")
$db = new Database(array(
    'driver' => 'mysql',
    'hostname' => 'localhost',
    'username' => 'root',
    'password' => '',
    'database' => 'my_db_name',
    'charset' => 'utf8',
));

Execute a SQL request

$db->execute('CREATE TABLE toto (column1 TEXT)');

Insert some data

$db->table('toto')->save(['column1' => 'test']);

or

$db->table('toto')->insert(['column1' => 'test']);

Transactions

$db->transaction(function ($db) {
    $db->table('toto')->save(['column1' => 'foo']);
    $db->table('toto')->save(['column1' => 'bar']);
});

or

$db->startTransaction();
// Do something...
$db->closeTransaction();

// Rollback
$db->cancelTransaction();

Fetch all data

$records = $db->table('toto')->findAll();

foreach ($records as $record) {
    var_dump($record['column1']);
}

Update something

$db->table('toto')->eq('id', 1)->save(['column1' => 'hey']);

You just need to add a condition to perform an update.

Remove rows

$db->table('toto')->lowerThan('column1', 10)->remove();

Sorting

$db->table('toto')->asc('column1')->findAll();

or

$db->table('toto')->desc('column1')->findAll();

or

#db->table('toto')->orderBy('column1', 'ASC')->findAll();

Limit and offset

$db->table('toto')->limit(10)->offset(5)->findAll();

Fetch only some columns

$db->table('toto')->columns('column1', 'column2')->findAll();

Fetch only one column

Many rows:

$db->table('toto')->findAllByColumn('column1');

One row:

$db->table('toto')->findOneColumn('column1');

Equals condition

$db->table('toto')
   ->equals('column1', 'hey')
   ->findAll();

or

$db->table('toto')
   ->eq('column1', 'hey')
   ->findAll();

Yout got: 'SELECT * FROM toto WHERE column1=?'

IN condition

$db->table('toto')
       ->in('column1', ['hey', 'bla'])
       ->findAll();

Like condition

Case-sensitive (only Mysql and Postgres):

$db->table('toto')
   ->like('column1', '%Foo%')
   ->findAll();

Not case-sensitive:

$db->table('toto')
   ->ilike('column1', '%foo%')
   ->findAll();

Lower than

$db->table('toto')
   ->lowerThan('column1', 2)
   ->findAll();

or

$db->table('toto')
   ->lt('column1', 2)
   ->findAll();

Lower than or equals

$db->table('toto')
   ->lowerThanOrEquals('column1', 2)
   ->findAll();

or

$db->table('toto')
   ->lte('column1', 2)
   ->findAll();

Greater than

$db->table('toto')
   ->greaterThan('column1', 3)
   ->findAll();

or

$db->table('toto')
   ->gt('column1', 3)
   ->findAll();

Greater than or equals

$db->table('toto')
   ->greaterThanOrEquals('column1', 3)
   ->findAll();

or

$db->table('toto')
    ->gte('column1', 3)
    ->findAll();

Multiple conditions

Each condition is joined by a AND.

$db->table('toto')
    ->like('column2', '%toto')
    ->gte('column1', 3)
    ->findAll();

How to make a OR condition:

$db->table('toto')
    ->beginOr()
    ->like('column2', '%toto')
    ->gte('column1', 3)
    ->closeOr()
    ->eq('column5', 'titi')
    ->findAll();

Debugging

Log generated queries:

$db->log_queries = true;

Mesure each query time:

$db->stopwatch = true;

Get the number of queries executed:

echo $db->nb_queries;

Get log messages:

print_r($db->getLogMessages());

Hashtable (key/value store)

How to use a table as a key/value store:

$db->execute(
     'CREATE TABLE toto (
         column1 TEXT NOT NULL UNIQUE,
         column2 TEXT default NULL
     )'
);

$db->table('toto')->insert(['column1' => 'option1', 'column2' => 'value1']);

Add/Replace some values:

$db->hashtable('toto')
   ->columnKey('column1')
   ->columnValue('column2')
   ->put(['option1' => 'new value', 'option2' => 'value2']));

Get all values:

$result = $db->hashtable('toto')->columnKey('column1')->columnValue('column2')->get();
print_r($result);

Array
(
    [option2] => value2
    [option1] => new value
)

or

$result = $db->hashtable('toto')->getAll('column1', 'column2');

Get a specific value:

$db->hashtable('toto')
   ->columnKey('column1')
   ->columnValue('column2')
   ->put(['option3' => 'value3']);

$result = $db->hashtable('toto')
             ->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:

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()" executes all migrations until to reach the correct version number.
  • If we are already on the last version nothing will happen.
  • The schema version for the driver Sqlite is stored inside a variable (PRAGMA user_version)
  • You can use that with a dependency injection controller.

Example:

$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:

PicoDb\Database::bootstrap('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:

PicoDb\Database::get('myinstance')->table(...)