From caae15042ad6642aa142cc54fcedcf314986987c Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sat, 20 Jun 2026 23:30:39 -0400 Subject: [PATCH 1/9] remove duplicated whereJson and all variants --- src/Db.php | 84 ------------------------------------------------------ 1 file changed, 84 deletions(-) diff --git a/src/Db.php b/src/Db.php index 7c1bc01..3c0aa1f 100644 --- a/src/Db.php +++ b/src/Db.php @@ -355,90 +355,6 @@ public function orWhere($condition, $comparator = null, $value = null): self return $this; } - * - * @param string $column The JSON column - * @param string $jsonKey The key within the JSON structure - * @param mixed $value The value to compare against - * @param string $comparator The comparison operator (default '=') - */ - public function whereJson(string $column, string $jsonKey, $value, string $comparator = '='): self - { - // Check if the value is an integer, and cast the JSON value to an integer - $jsonExpression = is_int($value) - # just incase: ? "CAST(JSON_EXTRACT($column, '$.$jsonKey') AS UNSIGNED)"; - ? "JSON_EXTRACT($column, '$.$jsonKey') + 0" - : "JSON_EXTRACT($column, '$.$jsonKey')"; - - $this->query = Builder::where($this->query, $jsonExpression, $value, $comparator); - $this->bind(...(Builder::$bindings)); - - return $this; - } - - /** - * Add a JSON where clause with OR comparator to the query - * - * @param string $column The JSON column - * @param string $jsonKey The key within the JSON structure - * @param mixed $value The value to compare against - * @param string $comparator The comparison operator (default '=') - */ - public function orWhereJson(string $column, string $jsonKey, $value, string $comparator = '='): self - { - $jsonExpression = is_int($value) - ? "JSON_EXTRACT($column, '$.$jsonKey') + 0" - : "JSON_EXTRACT($column, '$.$jsonKey')"; - - $this->query = Builder::where($this->query, $jsonExpression, $value, $comparator, 'OR'); - $this->bind(...(Builder::$bindings)); - - return $this; - } - - /** - * Add a JSON contains clause to the query - * - * @param string $column The JSON column - * @param mixed $value The value to check for - * @param string|null $jsonKey The key within the JSON structure (optional) - */ - public function whereJsonContains(string $column, $value, ?string $jsonKey = null): self - { - $jsonValue = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); - - $jsonExpression = $jsonKey - ? "JSON_CONTAINS($column, ?, '$.$jsonKey')" - : "JSON_CONTAINS($column, ?)"; - - Builder::$bindings[] = $jsonValue; - $this->query = Builder::where($this->query, $jsonExpression, 1, '='); - $this->bind(...(Builder::$bindings)); - - return $this; - } - - /** - * Add a JSON contains clause with OR comparator to the query - * - * @param string $column The JSON column - * @param mixed $value The value to check for - * @param string|null $jsonKey The key within the JSON structure (optional) - */ - public function orWhereJsonContains(string $column, $value, ?string $jsonKey = null): self - { - $jsonValue = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); - - $jsonExpression = $jsonKey - ? "JSON_CONTAINS($column, ?, '$.$jsonKey')" - : "JSON_CONTAINS($column, ?)"; - - Builder::$bindings[] = $jsonValue; - $this->query = Builder::where($this->query, $jsonExpression, 1, '=', 'OR'); - $this->bind(...(Builder::$bindings)); - - return $this; - } - /** * Fetch current query with all related data * From 5547ffd90c06e93622f30edba46546069eb68096 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sat, 20 Jun 2026 23:31:04 -0400 Subject: [PATCH 2/9] move test db connection to env --- .env.example.php | 11 +++++++++++ .gitignore | 1 + tests/mysql/connect.test.php | 14 ++++++++++---- tests/mysql/leaf-builder.test.php | 8 ++++---- 4 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 .env.example.php diff --git a/.env.example.php b/.env.example.php new file mode 100644 index 0000000..14cc340 --- /dev/null +++ b/.env.example.php @@ -0,0 +1,11 @@ + 'mysql', + 'DB_HOST' => 'eu-cdbr-west-03.cleardb.net', + 'DB_USERNAME' => 'b9607a8a6d5ebb', + 'DB_PASSWORD' => 'cc589b17', + 'DB_DATABASE' => 'heroku_fb1311a639bb407', +]; diff --git a/.gitignore b/.gitignore index f55ac7b..6de8016 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ composer.lock package-lock.json vendor/ test/ +.env.php # OS Generated .DS_Store* diff --git a/tests/mysql/connect.test.php b/tests/mysql/connect.test.php index 4131811..645c6ed 100644 --- a/tests/mysql/connect.test.php +++ b/tests/mysql/connect.test.php @@ -1,7 +1,13 @@ connect('eu-cdbr-west-03.cleardb.net', 'heroku_fb1311a639bb407', 'b9607a8a6d5ebb', 'cc589b17')) + expect($db->connectSync($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD'])) ->toBeInstanceOf(\PDO::class); $db->close(); @@ -38,7 +44,7 @@ it('inserts dummy user into `test` table', function () { $success = false; $db = new \Leaf\Db(); - $db->connect('eu-cdbr-west-03.cleardb.net', 'heroku_fb1311a639bb407', 'b9607a8a6d5ebb', 'cc589b17'); + $db->connect($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD']); try { $db->insert('test') @@ -67,7 +73,7 @@ it('selects dummy user from `test` table', function () { $db = new \Leaf\Db(); - $db->connect('eu-cdbr-west-03.cleardb.net', 'heroku_fb1311a639bb407', 'b9607a8a6d5ebb', 'cc589b17'); + $db->connect($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD']); $user = $db->select('test') ->where('name', 'Name') diff --git a/tests/mysql/leaf-builder.test.php b/tests/mysql/leaf-builder.test.php index 853ef99..1918f86 100644 --- a/tests/mysql/leaf-builder.test.php +++ b/tests/mysql/leaf-builder.test.php @@ -2,7 +2,7 @@ it('orders results in ascending order', function () { $db = new \Leaf\Db(); - $db->connect('eu-cdbr-west-03.cleardb.net', 'heroku_fb1311a639bb407', 'b9607a8a6d5ebb', 'cc589b17'); + $db->connect($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD']); $users = $db->select('test')->orderBy("created_at", "asc")->all(); @@ -12,7 +12,7 @@ it('orders results in descending order', function () { $db = new \Leaf\Db(); - $db->connect('eu-cdbr-west-03.cleardb.net', 'heroku_fb1311a639bb407', 'b9607a8a6d5ebb', 'cc589b17'); + $db->connect($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD']); $users = $db->select('test')->orderBy("created_at", "desc")->all(); @@ -22,7 +22,7 @@ it('orders by dummy name and count', function () { $db = new \Leaf\Db(); - $db->connect('eu-cdbr-west-03.cleardb.net', 'heroku_fb1311a639bb407', 'b9607a8a6d5ebb', 'cc589b17'); + $db->connect($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD']); $data = $db->select('test', 'name, COUNT(*)')->groupBy("created_at")->all(); @@ -31,7 +31,7 @@ it('orders by dummy name and count with limit and offset', function () { $db = new \Leaf\Db(); - $db->connect('eu-cdbr-west-03.cleardb.net', 'heroku_fb1311a639bb407', 'b9607a8a6d5ebb', 'cc589b17'); + $db->connect($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD']); $data = $db->select('test', 'name, COUNT(*)')->groupBy("created_at")->limit(1)->offset(1)->all(); From 247239be148ff1414e81b5d0374b58aa0627ee8f Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sat, 20 Jun 2026 23:54:56 -0400 Subject: [PATCH 3/9] update Db@whereJson docblock --- src/Db.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Db.php b/src/Db.php index 3c0aa1f..40fb133 100644 --- a/src/Db.php +++ b/src/Db.php @@ -356,7 +356,7 @@ public function orWhere($condition, $comparator = null, $value = null): self } /** - * Fetch current query with all related data + * Add a JSON where clause to db query * * @param string $column The JSON column * @param string $jsonKey The key within the JSON structure From 2b37539d9e805096cdbdba9688f701f9e107460b Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sat, 20 Jun 2026 23:56:23 -0400 Subject: [PATCH 4/9] don't override $_ENV setted in another place --- tests/mysql/connect.test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/mysql/connect.test.php b/tests/mysql/connect.test.php index 645c6ed..4869586 100644 --- a/tests/mysql/connect.test.php +++ b/tests/mysql/connect.test.php @@ -2,7 +2,7 @@ beforeAll(function () { if (file_exists(__DIR__ . '/../../.env.php')) { - $_ENV = require __DIR__ . '/../../.env.php'; + $_ENV += require __DIR__ . '/../../.env.php'; } $_ENV += require __DIR__ . '/../../.env.example.php'; From 042ff91c44e718c9a32a077720a854f87f41e5a4 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sat, 20 Jun 2026 23:58:09 -0400 Subject: [PATCH 5/9] load .env files in `leaf-builder.test.php` --- tests/mysql/leaf-builder.test.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/mysql/leaf-builder.test.php b/tests/mysql/leaf-builder.test.php index 1918f86..513548b 100644 --- a/tests/mysql/leaf-builder.test.php +++ b/tests/mysql/leaf-builder.test.php @@ -1,5 +1,13 @@ connect($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD']); From 4ffc482218884f71644ba253bfde4d2c79244030 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sat, 20 Jun 2026 23:59:36 -0400 Subject: [PATCH 6/9] remove db secrets --- .env.example.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.env.example.php b/.env.example.php index 14cc340..7e198d0 100644 --- a/.env.example.php +++ b/.env.example.php @@ -4,8 +4,8 @@ return [ 'DB_CONNECTION' => 'mysql', - 'DB_HOST' => 'eu-cdbr-west-03.cleardb.net', - 'DB_USERNAME' => 'b9607a8a6d5ebb', - 'DB_PASSWORD' => 'cc589b17', - 'DB_DATABASE' => 'heroku_fb1311a639bb407', + 'DB_HOST' => '127.0.0.1', + 'DB_USERNAME' => 'root', + 'DB_PASSWORD' => '', + 'DB_DATABASE' => 'test', ]; From 6c65655e349f5c64d02e6b21f94139fd43bf9ad6 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sun, 21 Jun 2026 00:13:51 -0400 Subject: [PATCH 7/9] use `connect` insteadof connectSync to save PDO in the Core state --- tests/mysql/connect.test.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/mysql/connect.test.php b/tests/mysql/connect.test.php index 4869586..175fa5d 100644 --- a/tests/mysql/connect.test.php +++ b/tests/mysql/connect.test.php @@ -30,8 +30,8 @@ try { $db = new \Leaf\Db(); - expect($db->connectSync($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD'])) - ->toBeInstanceOf(\PDO::class); + expect($db->connect($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD'])) + ->toBeInstanceOf(\Leaf\Db::class); $db->close(); $success = true; From 36cfc994e949a0b4e2476a6873faf0a46e557e95 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sun, 21 Jun 2026 00:29:17 -0400 Subject: [PATCH 8/9] test a real connection, not a deferred --- tests/mysql/connect.test.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/mysql/connect.test.php b/tests/mysql/connect.test.php index 175fa5d..b4b290a 100644 --- a/tests/mysql/connect.test.php +++ b/tests/mysql/connect.test.php @@ -30,8 +30,9 @@ try { $db = new \Leaf\Db(); - expect($db->connect($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD'])) - ->toBeInstanceOf(\Leaf\Db::class); + $pdo = $db->connectSync($_ENV['DB_HOST'], $_ENV['DB_DATABASE'], $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD']); + expect($pdo)->toBeInstanceOf(\PDO::class); + $db->connection($pdo); $db->close(); $success = true; From eb209869994134df3c31cc3290e60f9baa8c23e5 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Sun, 21 Jun 2026 00:32:55 -0400 Subject: [PATCH 9/9] create possibly uncreated test table in leaf-builder.test.php --- tests/mysql/leaf-builder.test.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/mysql/leaf-builder.test.php b/tests/mysql/leaf-builder.test.php index 513548b..a066995 100644 --- a/tests/mysql/leaf-builder.test.php +++ b/tests/mysql/leaf-builder.test.php @@ -6,6 +6,22 @@ } $_ENV += require __DIR__ . '/../../.env.example.php'; + + $pdo = new \PDO("mysql:host={$_ENV['DB_HOST']};dbname={$_ENV['DB_DATABASE']}", $_ENV['DB_USERNAME'], $_ENV['DB_PASSWORD']); + + $query = ' + CREATE TABLE IF NOT EXISTS `test` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `password` varchar(255) NOT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + '; + + $pdo->exec($query); + $pdo = null; }); it('orders results in ascending order', function () {