pontikis/dacapo

Dacapo - 简单的 PHP 数据库包装器

v1.0.2 2018-07-18 16:12 UTC

This package is not auto-updated.

Last update: 2024-09-29 05:09:19 UTC


README

Dacapo 类 (简单的 PHP 数据库包装器)

版权所有 Christos Pontikis http://www.pontikis.net

许可证 MIT https://raw.github.com/pontikis/dacapo/master/MIT_LICENSE

概述 - 数据库

  • 支持的 RDMBS: MySQLi (或 MariaDB), POSTGRESQL
  • 简单清晰的语法
  • 仅使用预处理语句
  • 支持的查询:单个 SELECT、UPDATE、INSERT、DELETE。
  • 支持事务
  • 轻松安全地编写 SQL。在参数值的位置使用 dacapo sql_placeholder(默认为 ?)。Dacapo 将从标准的 ANSI SQL 创建预处理语句。
$sql = 'SELECT procuct_name FROM products WHERE manufacturer = ? and type IN (?,?,?)';

备注

  • 对于 MYSQLi SELECT 预处理语句,需要 mysqlnd
  • 不支持持久数据库连接。
  • 不支持 BLOB 字段
  • 避免布尔字段,使用整数代替(1,0)
  • 使用 $ds->execute() 来执行一个或多个 SQL 语句(例如 SQL 脚本)。在这里不能使用预处理语句。

关于异常

您应该在您的应用程序中创建自定义包装器来捕获异常。

Dacapo 错误处理器将抛出 DacapoErrorException

如果您选择不使用 Dacapo 错误处理器,您将在自己的错误处理器中定义异常类型。

关于 Postgresql 序列

当您在 Postgres 中执行 INSERT 查询时,如果您想要获取主键列中的最后一个插入值,您还需要查询序列。在这种情况下使用 setQueryInsertPgSequence()。有三个选项

  • self::PG_SEQUENCE_NAME_AUTO 在这种情况下,序列名称将自动构建为 tablename_id_seq。这是默认设置(适用于 SERIAL 列)
  • null(在未定义主键的罕见情况下)
  • 序列的真实名称

记住,在每次 INSERT 查询后,query_insert_pg_sequence 将重置为默认的 self::PG_SEQUENCE_NAME_AUTO

文档

对于 HTML 文档,请参阅 docs/doxygen/html/ 文件夹(在浏览器中打开 index.html 文件)。

安装

使用 Composer(推荐)

composer require pontikis/dacapo

或老式方法

require_once 'path/to/Dacapo.php';
require_once 'path/to/DacapoErrorException.php';

使用示例

创建实例

use Pontikis\Database\Dacapo;
use Pontikis\Database\DacapoErrorException;

$db_settings = [
	'rdbms' => Dacapo::RDBMS_POSTGRES, // or Dacapo::RDBMS_MYSQLI for MySQL/MariaDB
	'db_server' => 'localhost',
	'db_user' => 'foo',
	'db_passwd' => 'bar',
	'db_name' => 'baz',
];

try {
	$ds = new Dacapo($db_settings);	
} catch (Exception $e) {
	// your code here
}

选择

$sql = 'SELECT id, firstname, lastname FROM customers WHERE lastname LIKE ?';
$bind_params = ['%' . $str . '%'];
try {
	$ds->select($sql, $bind_params);
	$customers = $ds->getData();
} catch (DacapoErrorException $e) {
	// your code here
}

遍历数据

if($ds->getNumRows() > 0) {
	foreach($customers as $customer) {
		$id = $customer['id'];
		$lastname = $customer['lastname'];
		$firstname = $customer['firstname'];
	}	
}

选择行

$sql = 'SELECT firstname, lastname FROM customers WHERE id = ?';
$bind_params = [$id];
try {
	$ds->select($sql, $bind_params);
	if(1 === $ds->getNumRows()) {
		$customer = $ds->getRow();		
		$firstname = $customer['firstname'];
		$lastname = $customer['lastname'];
	}
} catch (DacapoErrorException $e) {
	// your code here
}

插入

$sql = 'INSERT INTO customers (firstname, lastname) VALUES (?,?)';
$bind_params = [$firstname, $lastname];
try {
	$ds->insert($sql, $bind_params);
	$new_customer_id = $ds->getInsertId();
} catch (DacapoErrorException $e) {
	// your code here
}

更新

$sql = 'UPDATE customers SET category = ? WHERE balance > ?';
$bind_params = [$category, $balance];
try {
	$ds->update($sql, $bind_params);
	$affected_rows = $ds->getAffectedRows();
} catch (DacapoErrorException $e) {
	// your code here
}

删除

$sql = 'DELETE FROM customers WHERE category = ?';
$bind_params = [$category];
try {
	$ds->delete($sql, $bind_params);
	$affected_rows = $ds->getAffectedRows();	
} catch (DacapoErrorException $e) {
	// your code here
}

事务

try {
	$ds->beginTrans();

	// delete from customers
	$sql = 'DELETE FROM customers WHERE id = ?';
	$bind_params = [$customers_id];
	$ds->delete($sql, $bind_params);

	// delete from demographics
	$sql = 'DELETE FROM demographics WHERE id = ?';
	$bind_params = [$customer_demographics_id];
	$ds->delete($sql, $bind_params);

	$ds->commitTrans();
} catch (DacapoErrorException $e) {
	$ds->rollbackTrans();
	// your code here
}

实用函数

lower

// check for unique username (CASE IN-SENSITIVE)
$sql = "SELECT count('id') as total_rows FROM users WHERE {$ds->lower('username')} = ?";
$bind_params = [mb_strtolower($username)];
$ds->select($sql, $bind_params);
if($ds->getNumRows() > 0) {
	echo 'Username in use...';
}

limit

$limitSQL = $ds->limit($rows_per_page, ($page_num - 1) * $rows_per_page);

PHPUnit

在 Debian 9 Linux 服务器上进行的测试,使用

  • php 7
  • MariaDB Ver 15.1 Distrib 10.1.26-MariaDB(类似于 MySQL 5.7)
  • Postgres 9.6.7

测试数据库位于 tests/dbdata 文件夹中。在 tests/phpunit.xml 中自定义凭据。首先将 phpunit.dest.xml 复制到 phpunit.xml

MySQL 测试

测试 connectselect

./vendor/bin/phpunit --configuration tests/phpunit.xml tests/MySQLTest.php

mysqli 超时使某些测试变慢。运行一次,然后使用

./vendor/bin/phpunit --enforce-time-limit --configuration tests/phpunit.xml tests/MySQLTest.php

在这种情况下需要 PHP_Invoker https://github.com/sebastianbergmann/php-invoker

CUD 测试插入(C)更新(U)和删除(D)操作以及事务

./vendor/bin/phpunit --configuration tests/phpunit.xml tests/MySQLCUDTest.php

Postgres 测试

测试 connectselect

./vendor/bin/phpunit  --configuration tests/phpunit.xml tests/PostgresqlTest.php

CUD 测试插入(C)更新(U)和删除(D)操作以及事务

./vendor/bin/phpunit  --configuration tests/phpunit.xml tests/PostgresqlCUDTest.php

运行特定的测试,例如 testConnectFails1()

./vendor/bin/phpunit  --configuration tests/phpunit.xml tests/PostgresqlTest.php --filter '/testConnectFails1$/'

您不能在 CUD 测试中使用 --filter。实际上,每个 CUD 测试都依赖于之前的测试。

贡献

欢迎您的贡献。

  • 仅接受 dev 分支的拉取请求。
  • 请记住也要提交相关的 PHPUnit 测试。
  • 审查总是必要的。