Configure Database
In a new project, you should rename /etc/secret.dist.yml
to /etc/secret.yml
, and fill your database account information:
database:
driver: mysql
host: localhost
user: account
password: your_password
name: your_db_name
prefix: wind_
Get Database
In DatabaseModel, you can get internal DB object.
$this->db;
Or in other context, use IoC container to get Database:
$db = \Windwalker\Ioc::getDatabase();
$db = $container->get('system.database');
Execute A Query
This is an example of insert data.
$sql = 'INSERT INTO foo_table (title, state) VALUES ("Flower", 1)';
$db->setQuery($sql);
$db->execute();
Fetch records
Fetch multiple rows
This will fetch multiple rows from table, and every record will be an object.
$sql = 'SELECT * FROM foo_table WHERE state = 1';
$db->setQuery($sql);
$items = $db->loadAll();
Customize:
// Custom object class
$items = $db->loadAll(null, 'MyObject');
// Record as array with number as indexes
$items = $db->loadAll(null, 'array');
// Record as array with column name as indexes
$items = $db->loadAll(null, 'assoc');
// Use id column as $items index
$items = $db->loadAll('id', 'assoc');
Fetch one row
$sql = 'SELECT * FROM foo_table WHERE id = 3';
$db->setQuery($sql);
$item = $db->loadOne();
// Custom object class
$items = $db->loadAll('MyObject');
// Record as array with number as indexes
$items = $db->loadAll('array');
// Record as array with column name as indexes
$items = $db->loadAll('assoc');
Table Prefix
Add prefix
in secret.yml
config file, then DB object will auto replace all #__
with prefix in every query:
$items = $db->setQuery('SELECT * FROM #__articles')->loadAll();
// The query will be `SELECT * FROM foo_articles`
Iterating Over Results
$iterator = $db->setQuery('SELECT * FROM #__articles WHERE state = 1')->getIterator();
foreach ($iterator as $row)
{
// Deal with $row
}
It allows also to count the results.
$count = count($iterator);
Logging
Database\DatabaseDriver
implements the Psr\Log\LoggerAwareInterface
so is ready for intergrating with a logging package that supports that standard.
Drivers log all errors with a log level of LogLevel::ERROR
.
If debugging is enabled (using setDebug(true)
), all queries are logged with a log level of LogLevel::DEBUG
. The context of the log include:
- sql : The query that was executed.
- category : A value of "databasequery" is used.
An example to log error by Monolog
Add this to composer.json
require block.
"monolog/monolog" : "1.*"
Then we push Monolog into Database instance.
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Processor\PsrLogMessageProcessor;
// Create logger object
$logger = new Logger('sql');
// Push logger handler, use DEBUG level that we can log all information
$logger->pushHandler(new StreamHandler('path/to/log/sql.log', Logger::DEBUG));
// Use PSR-3 logger processor that we can replace {sql} with context like array('sql' => 'XXX')
$logger->pushProcessor(new PsrLogMessageProcessor);
// Push into DB
$db->setLogger($logger);
$db->setDebug(true);
// Do something
$db->setQuery('A WRONG QUERY')->execute();
This is the log file:
[2014-07-29 07:25:22] sql.DEBUG: A WRONG QUERY {"sql":"A WRONG QUERY","category":"databasequery","trace":[...]} []
[2014-07-29 07:36:01] sql.ERROR: Database query failed (error #42000): SQL: 42000, 1064, You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'A WRONG QUERY' at line 1 {"code":42000,"message":"SQL: 42000, 1064, You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'A WRONG QUERY' at line 1"} []
If you found a typo or error, please help us improve this document.