diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml
new file mode 100644
index 0000000..c43789d
--- /dev/null
+++ b/.github/workflows/phpunit.yml
@@ -0,0 +1,90 @@
+name: PHPUnit
+
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ services:
+ mysql:
+ image: mysql:5.7
+ env:
+ MYSQL_ALLOW_EMPTY_PASSWORD: yes
+ MYSQL_DATABASE: test
+ ports:
+ - 3306:3306
+ options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
+ postgres:
+ image: postgres
+ env:
+ POSTGRES_PASSWORD: postgres
+ POSTGRES_USER: postgres
+ POSTGRES_DB: test
+ ports:
+ - 5432:5432
+ options:
+ --health-cmd pg_isready
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+
+ strategy:
+ fail-fast: true
+ matrix:
+ php: [ 8.0, 8.1, 8.2, 8.3, 8.4 ]
+
+ name: PHP ${{ matrix.php }}
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ tools: composer:v2
+ coverage: xdebug
+
+ - name: Validate composer.json and composer.lock
+ run: composer validate
+
+ - name: Install dependencies
+ if: steps.composer-cache.outputs.cache-hit != 'true'
+ run: composer install --prefer-dist --no-progress --no-suggest
+
+ - name: Run test suite
+ run: ./vendor/bin/phpunit -v
+
+ - name: Run Coveralls
+ env:
+ COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ COVERALLS_PARALLEL: true
+ COVERALLS_FLAG_NAME: ${{ runner.os }} - ${{ matrix.php }}
+ run: ./vendor/bin/php-coveralls --coverage_clover=build/logs/clover.xml -v
+
+ upload-coverage:
+ runs-on: ubuntu-latest
+ needs: [ test ]
+ steps:
+ - name: Coveralls Finished
+ uses: coverallsapp/github-action@master
+ with:
+ github-token: ${{ secrets.GITHUB_TOKEN }}
+ parallel-finished: true
+
+ semantic-release:
+ runs-on: ubuntu-latest
+ needs: [ test, upload-coverage ]
+ steps:
+ - uses: actions/checkout@v3
+ - uses: actions/setup-node@v3
+ with:
+ node-version: 'lts/*'
+
+ - name: Run semantic-release
+ if: github.repository == 'leeqvip/database' && github.event_name == 'push'
+ env:
+ GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
+ run: npx semantic-release
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cf47104
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+/vendor/
+
+composer.lock
+
+.vscode
+.idea
+*.iml
+
+# coverage report
+/build
+
+.phpunit.*
+phpunit.xml
\ No newline at end of file
diff --git a/.releaserc.yml b/.releaserc.yml
new file mode 100644
index 0000000..4a17b28
--- /dev/null
+++ b/.releaserc.yml
@@ -0,0 +1,4 @@
+plugins:
+ - "@semantic-release/commit-analyzer"
+ - "@semantic-release/release-notes-generator"
+ - "@semantic-release/github"
\ No newline at end of file
diff --git a/README.md b/README.md
index c50d72c..7a93c9b 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,11 @@
# Database library for PHP
+[](https://github.com/leeqvip/database/actions/workflows/phpunit.yml)
+[](https://coveralls.io/github/leeqvip/database)
+[](https://packagist.org/packages/leeqvip/database)
+[](https://packagist.org/packages/leeqvip/database)
+[](https://packagist.org/packages/leeqvip/database)
+
PDO database library for PHP.
the current supported databases are:
diff --git a/composer.json b/composer.json
index 9c4b108..7589d13 100644
--- a/composer.json
+++ b/composer.json
@@ -1,21 +1,35 @@
{
- "name": "leeqvip/database",
- "keywords": ["pdo", "database", "orm", "framework"],
- "description": "PDO database library",
- "authors": [
- {
- "name": "leeqvip",
- "email": "leeqvip@gmail.com"
- }
- ],
- "license": "Apache-2.0",
- "require": {
- "php": ">=5.4.0",
- "ext-pdo": "*"
- },
- "autoload": {
- "psr-4": {
- "Leeqvip\\Database\\": "src/"
- }
- }
+ "name": "leeqvip/database",
+ "keywords": [
+ "pdo",
+ "database",
+ "orm",
+ "framework"
+ ],
+ "description": "PDO database library",
+ "authors": [
+ {
+ "name": "leeqvip",
+ "email": "leeqvip@gmail.com"
+ }
+ ],
+ "license": "Apache-2.0",
+ "require": {
+ "php": ">=8.0",
+ "ext-pdo": "*"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.6",
+ "php-coveralls/php-coveralls": "^2.7"
+ },
+ "autoload": {
+ "psr-4": {
+ "Leeqvip\\Database\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Tests\\": "tests/"
+ }
+ }
}
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..8db31af
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,34 @@
+
+
+
+
+ ./src
+
+
+
+
+
+
+
+
+ ./tests/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Connection.php b/src/Connection.php
index 73b8b29..e7e7d22 100644
--- a/src/Connection.php
+++ b/src/Connection.php
@@ -37,7 +37,7 @@ public function __construct(array $config = [])
$this->connector = new $connector();
}
- public function getPdo()
+ public function getPdo(): PDO
{
if (is_null($this->pdo)) {
$this->connect();
diff --git a/tests/.gitignore b/tests/.gitignore
new file mode 100644
index 0000000..3997bea
--- /dev/null
+++ b/tests/.gitignore
@@ -0,0 +1 @@
+*.db
\ No newline at end of file
diff --git a/tests/ConnectionTest.php b/tests/ConnectionTest.php
new file mode 100644
index 0000000..8119112
--- /dev/null
+++ b/tests/ConnectionTest.php
@@ -0,0 +1,85 @@
+getPDO();
+ $pdo->exec("DROP TABLE IF EXISTS users");
+ $pdo->exec(<<initConfig();
+ $this->initDatabase();
+ }
+
+ protected function getConnection()
+ {
+ return new Connection($this->config);
+ }
+
+ protected function getPDO(): \PDO
+ {
+ return $this->getConnection()->getPdo();
+ }
+
+ public function testQuery()
+ {
+ $this->init();
+ $this->getPDO()->exec("INSERT INTO users (id, name, nickname, created_at) VALUES (100, 'alice', 'Small Flower', '2025-05-17 13:28:56')");
+
+ $users = $this->getConnection()->query("SELECT * FROM users");
+ $this->assertCount(1, $users);
+
+ $users = $this->getConnection()->query("SELECT * FROM users WHERE id = :id", ['id' => 100]);
+ $this->assertCount(1, $users);
+
+ $this->assertEquals('100', $users[0]['id']);
+ $this->assertEquals('alice', $users[0]['name']);
+ $this->assertEquals('Small Flower', $users[0]['nickname']);
+ }
+
+ public function testExecute()
+ {
+ $this->init();
+ $conn = $this->getConnection();
+
+ $users = $conn->query("SELECT * FROM users");
+ $this->assertCount(0, $users);
+ $conn->execute(
+ "INSERT INTO users (id, name, nickname, created_at) VALUES (:id, :name, :nickname, '2025-05-17 13:28:56')",
+ [
+ 'id' => 200,
+ 'name' => 'bob',
+ 'nickname' => 'Small Angel',
+ ],
+ );
+
+ $users = $conn->query("SELECT * FROM users");
+ $this->assertCount(1, $users);
+
+ $this->assertEquals('200', $users[0]['id']);
+ $this->assertEquals('bob', $users[0]['name']);
+ $this->assertEquals('Small Angel', $users[0]['nickname']);
+ }
+}
diff --git a/tests/MysqlConnectionTest.php b/tests/MysqlConnectionTest.php
new file mode 100644
index 0000000..a648863
--- /dev/null
+++ b/tests/MysqlConnectionTest.php
@@ -0,0 +1,22 @@
+config = [
+ 'type' => 'mysql', // mysql,pgsql,sqlite,sqlsrv
+ 'hostname' => getenv('DB_HOST'),
+ 'database' => getenv('DB_DATABASE'),
+ 'username' => getenv('DB_USERNAME'),
+ 'password' => getenv('DB_PASSWORD'),
+ 'hostport' => getenv('DB_PORT'),
+ ];
+ }
+}
diff --git a/tests/PostgresConnectionTest.php b/tests/PostgresConnectionTest.php
new file mode 100644
index 0000000..764ce5c
--- /dev/null
+++ b/tests/PostgresConnectionTest.php
@@ -0,0 +1,22 @@
+config = [
+ 'type' => 'pgsql', // mysql,pgsql,sqlite,sqlsrv
+ 'hostname' => getenv('PG_HOST'),
+ 'database' => getenv('PG_DATABASE'),
+ 'username' => getenv('PG_USERNAME'),
+ 'password' => getenv('PG_PASSWORD'),
+ 'hostport' => getenv('PG_PORT'),
+ ];
+ }
+}
diff --git a/tests/SqliteConnectionTest.php b/tests/SqliteConnectionTest.php
new file mode 100644
index 0000000..2a4db58
--- /dev/null
+++ b/tests/SqliteConnectionTest.php
@@ -0,0 +1,19 @@
+config = [
+ 'type' => 'sqlite', // mysql,pgsql,sqlite,sqlsrv
+ 'database' => __DIR__.'/test.db',
+ ];
+ }
+}
+