├── .editorconfig
├── .gitignore
├── LICENSE
├── README.md
├── composer.json
├── phpcs.xml
├── phpunit.xml
├── src
├── Api
│ ├── AlterInterface.php
│ ├── CreateInterface.php
│ ├── DeleteInterface.php
│ ├── DropInterface.php
│ ├── SelectInterface.php
│ └── UpdateInterface.php
├── Connect.php
├── DB.php
├── QueryFactory.php
├── SqlGenerator.php
├── Statement
│ ├── Alter.php
│ ├── Create.php
│ ├── Delete.php
│ ├── Drop.php
│ ├── Insert.php
│ ├── Select.php
│ └── Update.php
└── Utilities.php
└── tests
├── CreateTest.php
├── SelectTest.php
├── Statement
├── CreateApi.php
├── SelectApi.php
└── UpdateApi.php
└── UpdateTest.php
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | trim_trailing_whitespace = true
7 | indent_style = tab
8 | indent_size = 4
9 | tab_width = 4
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | lerna-debug.log*
8 | vendor
9 | composer.lock
10 |
11 | .DS_Store
12 | .github/
13 | doc/
14 |
15 | .phpunit.result.cache
16 |
17 | # Diagnostic reports (https://nodejs.org/api/report.html)
18 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
19 |
20 | # Runtime data
21 | pids
22 | *.pid
23 | *.seed
24 | *.pid.lock
25 |
26 | # Directory for instrumented libs generated by jscoverage/JSCover
27 | lib-cov
28 |
29 | # Coverage directory used by tools like istanbul
30 | coverage
31 | *.lcov
32 |
33 | # nyc test coverage
34 | .nyc_output
35 |
36 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
37 | .grunt
38 |
39 | # Bower dependency directory (https://bower.io/)
40 | bower_components
41 |
42 | # node-waf configuration
43 | .lock-wscript
44 |
45 | # Compiled binary addons (https://nodejs.org/api/addons.html)
46 | build/Release
47 |
48 | # Dependency directories
49 | node_modules/
50 | jspm_packages/
51 |
52 | # TypeScript v1 declaration files
53 | typings/
54 |
55 | # TypeScript cache
56 | *.tsbuildinfo
57 |
58 | # Optional npm cache directory
59 | .npm
60 |
61 | # Optional eslint cache
62 | .eslintcache
63 |
64 | # Microbundle cache
65 | .rpt2_cache/
66 | .rts2_cache_cjs/
67 | .rts2_cache_es/
68 | .rts2_cache_umd/
69 |
70 | # Optional REPL history
71 | .node_repl_history
72 |
73 | # Output of 'npm pack'
74 | *.tgz
75 |
76 | # Yarn Integrity file
77 | .yarn-integrity
78 |
79 | # dotenv environment variables file
80 | .env
81 | .env.test
82 |
83 | # parcel-bundler cache (https://parceljs.org/)
84 | .cache
85 |
86 | # Next.js build output
87 | .next
88 |
89 | # Nuxt.js build / generate output
90 | .nuxt
91 | dist
92 |
93 | # Gatsby files
94 | .cache/
95 | # Comment in the public line in if your project uses Gatsby and *not* Next.js
96 | # https://nextjs.org/blog/next-9-1#public-directory-support
97 | # public
98 |
99 | # vuepress build output
100 | .vuepress/dist
101 |
102 | # Serverless directories
103 | .serverless/
104 |
105 | # FuseBox cache
106 | .fusebox/
107 |
108 | # DynamoDB Local files
109 | .dynamodb/
110 |
111 | # TernJS port file
112 | .tern-port
113 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Keramot UL Islam
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WP Query Builder
2 |
3 | Relational Database Query builder for WordPress.
4 | WP Query Builder uses PDO
for database queries. It has zero dependencies with third-party query builders or any other composer library.
5 |
6 |
7 |
8 |
9 | # Documentation
10 | Documentation website [here](https://wp-querybuilder.pages.dev/).
11 |
12 | This Query Builder is also used in [Kathamo](https://kathamo.dev) Framework. Kathamo is a modern framework for WordPress plugin development.
13 |
14 |
15 |
16 | ## Examples
17 |
18 | ### Create Table
19 | ``` php
20 | DB::create('querybuilder')
21 | ->column('ID')->bigInt()->unsigned()->autoIncrement()->primary()->required()
22 | ->column('user_id')->bigInt()->unsigned()->required()
23 | ->column('name')->string(255)->required()
24 | ->column('email')->string(255)->nullable()
25 | ->column('settings')->enum(['active', 'inactive'])
26 | ->column('created_at')->timestamp('now', 'current')
27 | ->foreignKey('user_id', 'users.ID', 'cascade')
28 | ->index(['ID'])
29 | ->execute();
30 | ```
31 |
32 |
33 |
34 | ### Insert Statement
35 | ``` php
36 | DB::insert('querybuilder', [
37 | [
38 | 'name' => 'Keramot UL Islam',
39 | 'email' => 'keramotul.@gmail.com',
40 | ]
41 | ]);
42 | ```
43 |
44 |
45 |
46 | ### Update Statement
47 |
48 | ``` php
49 | DB::update('querybuilders', [
50 | 'name' => 'Keramot UL',
51 | 'email' => 'keramotul.islam@gmail.com'
52 | ])
53 | ->where('ID', '=', 10)
54 | ->andWhere('name', '=', 'Abm Sourav')
55 | ->execute();
56 | ```
57 |
58 |
59 |
60 | ### Select Statement
61 |
62 | ``` php
63 | $result =
64 | DB::select('qb.ID', 'qb.name, qb.email')
65 | ->from('querybuilders')
66 | ->alias('qb')
67 | ->groupBy('name')
68 | ->get();
69 |
70 |
71 | // *** where clouse
72 | $result =
73 | DB::select('posts.ID', 'posts.post_title')
74 | ->distinct()
75 | ->from('posts posts')
76 | ->where('posts.post_status', '=', 'publish')
77 | ->orderBy('post_title', 'DESC')
78 | ->limit(10)->offset(2)
79 | ->get();
80 |
81 | // *** JOIN
82 | DB::select('users.display_name name')
83 | ->count('posts.ID', 'posts')
84 | ->from('users users')
85 | ->join('posts posts')
86 | ->where('posts.post_status', '=', 'publish')
87 | ->andWhere('posts.post_type', '=', 'post')
88 | ->get();
89 |
90 | // raw sql
91 | DB::select('posts.post_title')
92 | ->from('posts posts')
93 | ->raw("WHERE posts.post_type = 'post'")
94 | ->andWhere('posts.post_status', '=', 'publish')
95 | ->raw("LIMIT 10")
96 | ->get();
97 | ```
98 |
99 |
100 |
101 | ### Delete Statement
102 |
103 | ``` php
104 | // delete one row
105 | DB::delete('posts')
106 | ->where('ID', '=', 3)
107 | ->execute();
108 |
109 | // delete all records
110 | DB::delete('posts')->execute();
111 | ```
112 |
113 |
114 |
115 | ### Drop Statement
116 |
117 | ``` php
118 | DB::drop('posts');
119 | DB::dropIfExists('terms');
120 | ```
121 |
122 |
123 |
124 | ### Alter Statement
125 |
126 | ``` php
127 | DB::alter('cv_users')
128 | ->modify('name', 'username')->string(455)->required()
129 | ->modify('settings')->json()
130 | ->execute();
131 | ```
132 |
133 |
134 |
135 |
136 | ### Single instence
137 |
138 | Expressions also can be exicuted with one instence of DB
class. By doing this database connection will be stablished only once.
139 |
140 |
141 | ``` php
142 | $db = new DB();
143 |
144 | $result =
145 | $db::select('posts.ID', 'posts.post_title')
146 | ...
147 |
148 | $db::create('meta')
149 | ...
150 | ```
151 |
152 |
153 |
154 |
155 | ### Database Connection
156 | By default database connection will set out of the box, automaically. But you can also manually input database configurations. This way, you also can debug your database queries from terminal.
157 |
158 | ```php
159 | $db = DB::setConnection(
160 | [
161 | "dbhost" => 'mysql_host',
162 | "dbname" => 'database_name',
163 | "dbuser" => 'database_user',
164 | "dbpassword" => 'database_password',
165 | "prefix" => 'database_table_prefix'
166 | ]
167 | );
168 | ```
169 |
170 |
171 |
172 |
173 | ### Driver
174 |
175 | The default driver is `pdo`. But if you want to use `wpdb` which uses Mysqli, you also can do that by changing the driver.
176 | ``` php
177 | $db = new DB('wpdb');
178 |
179 | $db::select('posts.post_title')
180 | ->from('posts posts')
181 | ->get();
182 | ```
183 |
184 |
185 |
186 |
187 | ## Dev Envirenment Setup for Contributors
188 | Want to contribute to this package? Please follow the steps below.
189 |
190 |
191 | - Create a local WordPress envirenment setup.
192 | - Create a basic plugin.
193 | - Run
composer init
into the plugin.
194 | - Clone
git@github.com:CodesVault/howdy_qb.git
into plugin folder.
195 | -
196 | Add repository for local package in plugin's
composer.json
.
197 |
198 | "repositories": [
199 | {
200 | "type": "path",
201 | "url": "./howdy_qb",
202 | "options": {
203 | "symlink": true
204 | }
205 | }
206 | ],
207 |
208 |
209 | - Require this package.
composer require "codesvault/howdy-qb @dev"
210 |
211 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "codesvault/howdy-qb",
3 | "description": "Mysql Query Builder for WordPress",
4 | "version": "1.6.4",
5 | "minimum-stability": "stable",
6 | "scripts": {
7 | "test": "phpunit",
8 | "phpcs": "phpcs ",
9 | "phpcbf": "phpcbf ",
10 | "post-package-install": "phpcs --config-set installed_paths vendor/phpcompatibility/php-compatibility"
11 | },
12 | "autoload": {
13 | "psr-4": {
14 | "CodesVault\\Howdyqb\\": "src/"
15 | }
16 | },
17 | "autoload-dev": {
18 | "psr-4": {
19 | "CodesVault\\Howdyqb\\Tests\\": "tests/"
20 | }
21 | },
22 | "authors": [
23 | {
24 | "name": "CodesVault",
25 | "email": "codesvault@gmail.com"
26 | },
27 | {
28 | "name": "Keramot UL Islam",
29 | "email": "keramotul.islam@gmail.com"
30 | }
31 | ],
32 | "license": "MIT",
33 | "require": {
34 | "php": ">=7.1"
35 | },
36 | "require-dev": {
37 | "phpunit/phpunit": "^9.5",
38 | "symfony/var-dumper": "^5.4",
39 | "squizlabs/php_codesniffer": "^3.7",
40 | "wp-coding-standards/wpcs": "^2.3",
41 | "phpcompatibility/php-compatibility": "^9.3"
42 | },
43 | "keywords": [
44 | "wordpress",
45 | "database",
46 | "query builder",
47 | "pdo",
48 | "mysqli",
49 | "query",
50 | "builder",
51 | "mysql",
52 | "wp"
53 | ],
54 | "archive": {
55 | "exclude": [
56 | ".editorconfig",
57 | ".gitignore",
58 | "tests",
59 | "phpunit.xml",
60 | "phpcs.xml"
61 | ]
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | /tests/*
18 | /vendor/*
19 | /.github/*
20 |
21 |
22 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
13 |
16 |
17 |
18 | ./tests
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/Api/AlterInterface.php:
--------------------------------------------------------------------------------
1 | dbhost, ENT_QUOTES);
20 | $dbname = htmlspecialchars($configs->dbname, ENT_QUOTES);
21 | $user = htmlspecialchars($configs->dbuser, ENT_QUOTES);
22 | $password = $configs->dbpassword;
23 | $dns = "mysql:host=$host;dbname=$dbname";
24 |
25 | try {
26 | return new \PDO($dns, $user, $password);
27 | } catch (\PDOException $exception) {
28 | Utilities::throughException($exception);
29 | }
30 | }
31 |
32 | public static function setManualConnection(array $configs = [])
33 | {
34 | $configurations = [];
35 | if (! defined('DB_HOST')) {
36 | $path = explode('/wp-content', dirname(__DIR__));
37 | if (! empty($path) && ! file_exists($path[0] . '/wp-config.php')) {
38 | throw new \Exception('wp-config.php file not found');
39 | }
40 | require $path[0] . '/wp-config.php';
41 |
42 | $configurations = [
43 | "dbhost" => DB_HOST,
44 | "dbname" => DB_NAME,
45 | "dbuser" => DB_USER,
46 | "dbpassword" => DB_PASSWORD,
47 | "prefix" => $table_prefix,
48 | ];
49 | }
50 |
51 | $configurations = array_merge($configurations, $configs);
52 | static::$configs = (object)$configurations;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/DB.php:
--------------------------------------------------------------------------------
1 | selectQuery();
17 | $query = $query->columns(...$columns);
18 | return $query;
19 | }
20 |
21 | public static function insert(string $table_name, array $data)
22 | {
23 | $factory = new self(static::$driver);
24 | $factory->insertQuery($table_name, $data);
25 | return $factory;
26 | }
27 |
28 | public static function create(string $table_name): CreateInterface
29 | {
30 | $factory = new self(static::$driver);
31 | $create = $factory->createQuery($table_name);
32 | return $create;
33 | }
34 |
35 | public static function alter(string $table_name): AlterInterface
36 | {
37 | $factory = new self(static::$driver);
38 | $alter = $factory->alterQuery($table_name);
39 | return $alter;
40 | }
41 |
42 | public static function update(string $table_name, array $data): UpdateInterface
43 | {
44 | $factory = new self(static::$driver);
45 | $update = $factory->updateQuery($table_name, $data);
46 | return $update;
47 | }
48 |
49 | public static function delete(string $table_name): DeleteInterface
50 | {
51 | $factory = new self(static::$driver);
52 | $delete = $factory->deleteQuery($table_name);
53 | return $delete;
54 | }
55 |
56 | public static function drop(string $table_name)
57 | {
58 | $factory = new self(static::$driver);
59 | $drop = $factory->dropQuery($table_name);
60 | $drop->drop();
61 | }
62 |
63 | public static function dropIfExists(string $table_name)
64 | {
65 | $factory = new self(static::$driver);
66 | $drop = $factory->dropQuery($table_name);
67 | return $drop->dropIfExists();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/QueryFactory.php:
--------------------------------------------------------------------------------
1 | db) return;
28 |
29 | static::$driver = $driver;
30 |
31 | if ('pdo' === $driver) {
32 | $this->db = Connect::pdo();
33 | } elseif ('wpdb' === $driver) {
34 | global $wpdb;
35 | $this->db = $wpdb;
36 | }
37 | }
38 |
39 | /**
40 | * Set manula connection
41 | *
42 | * @param array $configs
43 | * @param string $driver
44 | * @return CodesVault\Howdyqb\DB
45 | */
46 | public static function setConnection($configs = [], $driver = 'pdo')
47 | {
48 | if (! empty($configs)) {
49 | Connect::setManualConnection($configs);
50 | }
51 | static::$config = $configs;
52 | return new DB($driver);
53 | }
54 |
55 | protected function selectQuery(): SelectInterface
56 | {
57 | return new Select($this->db);
58 | }
59 |
60 | protected function insertQuery(string $table_name, array $data)
61 | {
62 | return new Insert($this->db, $table_name, $data);
63 | }
64 |
65 | protected function createQuery(string $table_name)
66 | {
67 | return new Create($this->db, $table_name);
68 | }
69 |
70 | protected function alterQuery(string $table_name)
71 | {
72 | return new Alter($this->db, $table_name);
73 | }
74 |
75 | protected function updateQuery(string $table_name, array $data)
76 | {
77 | return new Update($this->db, $table_name, $data);
78 | }
79 |
80 | protected function deleteQuery(string $table_name)
81 | {
82 | return new Delete($this->db, $table_name);
83 | }
84 |
85 | protected function dropQuery(string $table_name)
86 | {
87 | return new Drop($this->db, $table_name);
88 | }
89 |
90 | public static function getConfig()
91 | {
92 | return static::$config;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/SqlGenerator.php:
--------------------------------------------------------------------------------
1 | $value) {
14 | if ($key == 'start') continue;
15 | $query .= $value . ' ';
16 | }
17 | return trim($query);
18 | }
19 |
20 | public static function insert(array $sql)
21 | {
22 | $query = '';
23 | if (isset($sql['start'])) {
24 | $query .= $sql['start'] . ' ';
25 | unset($sql['start']);
26 | }
27 | foreach ($sql as $value) {
28 | $query .= $value . ' ';
29 | }
30 | return trim($query);
31 | }
32 |
33 | public static function create(array $sql)
34 | {
35 | $query = '';
36 | if (isset($sql['start'])) {
37 | $query .= $sql['start'] . ' ';
38 | }
39 | if (isset($sql['table_name'])) {
40 | $query .= $sql['table_name'] . ' ';
41 | }
42 |
43 | $query .= '(';
44 | foreach ($sql as $ex => $expression) {
45 | if ( $ex == 'start' || $ex == 'table_name' ) continue;
46 |
47 | if (is_array($expression)) {
48 | foreach ($expression as $name => $column) {
49 | $expression[$name] = '`'. $name . '` ' . implode(' ', $column);
50 | }
51 | $query .= implode(', ', $expression);
52 |
53 | continue;
54 | }
55 |
56 | $query .= ', ' . $expression . '';
57 | }
58 |
59 | $query .= ')';
60 |
61 | return trim($query);
62 | }
63 |
64 | public static function alter(array $sql)
65 | {
66 | $query = '';
67 | if (isset($sql['start'])) {
68 | $query .= $sql['start'] . ' ';
69 | }
70 | foreach ($sql as $key => $value) {
71 | if ($key == 'start') continue;
72 | $query .= $value . ' ';
73 | }
74 | $query = trim($query);
75 | return $query . ";";
76 | }
77 |
78 | public static function update(array $sql)
79 | {
80 | $query = '';
81 | if (isset($sql['start'])) {
82 | $query .= $sql['start'] . ' ';
83 | }
84 | if (isset($sql['set_columns'])) {
85 | $query .= $sql['set_columns'] . ' ';
86 | }
87 | foreach ($sql as $key => $value) {
88 | if ($key == 'start' || $key == 'set_columns') continue;
89 | $query .= $value . ' ';
90 | }
91 | return trim($query);
92 | }
93 |
94 | public static function delete(array $sql)
95 | {
96 | $query = '';
97 | if (isset($sql['start'])) {
98 | $query .= $sql['start'] . ' ';
99 | }
100 | if (isset($sql['drop'])) {
101 | $query = $sql['drop'] . ' ';
102 | return trim($query);
103 | }
104 | foreach ($sql as $key => $value) {
105 | if ($key == 'start') continue;
106 | $query .= $value . ' ';
107 | }
108 | return trim($query);
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/Statement/Alter.php:
--------------------------------------------------------------------------------
1 | db = $db;
22 | $this->table_name = $table_name;
23 |
24 | $this->start();
25 | }
26 |
27 | public function add(string $column): self
28 | {
29 | $this->column_name = $column;
30 | if ($this->hasColumn($column)) {
31 | $this->column_exists = true;
32 | }
33 |
34 | $this->sql[$column] = "ADD $column";
35 | return $this;
36 | }
37 |
38 | public function modify(string $old_column, string $new_column = ''): self
39 | {
40 | $this->column_name = $new_column;
41 | $this->sql[$new_column] = trim("MODIFY COLUMN $old_column $new_column");
42 | return $this;
43 | }
44 |
45 | public function drop(string $column): self
46 | {
47 | $this->sql[$column] = "DROP COLUMN $column";
48 | return $this;
49 | }
50 |
51 | public function int(int $size = 255): self
52 | {
53 | $this->sql[$this->column_name] .= " INT($size)";
54 | return $this;
55 | }
56 |
57 | public function bigInt(int $size = 255): self
58 | {
59 | $this->sql[$this->column_name] .= " BIGINT($size)";
60 | return $this;
61 | }
62 |
63 | public function double(int $size = 255, int $d = 2): self
64 | {
65 | $this->sql[$this->column_name] .= " DOUBLE($size, $d)";
66 | return $this;
67 | }
68 |
69 | public function boolean(): self
70 | {
71 | $this->sql[$this->column_name] .= " BOOLEAN";
72 | return $this;
73 | }
74 |
75 | public function string(int $size = 255): self
76 | {
77 | $this->sql[$this->column_name] .= " VARCHAR($size)";
78 | return $this;
79 | }
80 |
81 | public function text(int $size = 10000): self
82 | {
83 | $this->sql[$this->column_name] .= " TEXT($size)";
84 | return $this;
85 | }
86 |
87 | public function longText(int $size): self
88 | {
89 | $this->sql[$this->column_name] .= " LONGTEXT($size)";
90 | return $this;
91 | }
92 |
93 | public function json(): self
94 | {
95 | $this->sql[$this->column_name] .= " JSON";
96 | return $this;
97 | }
98 |
99 | public function required(): self
100 | {
101 | $this->sql[$this->column_name] .= " NOT NULL";
102 | return $this;
103 | }
104 |
105 | public function primary($columns = []): self
106 | {
107 | if (! empty($columns)) {
108 | $this->sql['primary'] = "PRIMARY KEY (" . implode(',', $columns) . ")";
109 | return $this;
110 | }
111 | $this->sql[$this->column_name] .= " PRIMARY KEY";
112 | return $this;
113 | }
114 |
115 | public function index(array $columns): self
116 | {
117 | $this->sql['index'] = "INDEX (" . implode(',', $columns) . ")";
118 | return $this;
119 | }
120 |
121 | public function date(): self
122 | {
123 | $this->sql[$this->column_name] .= " DATE";
124 | return $this;
125 | }
126 |
127 | public function dateTime(): self
128 | {
129 | $this->sql[$this->column_name] .= " DATETIME";
130 | return $this;
131 | }
132 |
133 | public function timestamp($default = null, $on_update = null): self
134 | {
135 | $this->sql[$this->column_name] .= " TIMESTAMP";
136 |
137 | if ($default === 'now') {
138 | $this->sql[$this->column_name] .= " DEFAULT CURRENT_TIMESTAMP";
139 | } elseif ($default && $default !== 'now') {
140 | $this->sql[$this->column_name] .= " DEFAULT " . $default;
141 | }
142 |
143 | if ($on_update === 'current') {
144 | $this->sql[$this->column_name] .= " ON UPDATE CURRENT_TIMESTAMP";
145 | } elseif ($on_update && $on_update !== 'current') {
146 | $this->sql[$this->column_name] .= " ON UPDATE " . $on_update;
147 | }
148 |
149 | return $this;
150 | }
151 |
152 | public function unsigned(): self
153 | {
154 | $this->sql[$this->column_name] .= " UNSIGNED";
155 | return $this;
156 | }
157 |
158 | public function autoIncrement(): self
159 | {
160 | $this->sql[$this->column_name] .= " AUTO_INCREMENT";
161 | return $this;
162 | }
163 |
164 | public function default($value): self
165 | {
166 | $val = is_string($value) ? "'$value'" : $value;
167 | $this->sql[$this->column_name] .= " DEFAULT $val";
168 | return $this;
169 | }
170 |
171 | public function nullable(): self
172 | {
173 | return $this->default('NULL');
174 | }
175 |
176 | public function foreignKey(string $column, string $reference_table, string $reference_column): self
177 | {
178 | $table_name = Utilities::get_db_configs()->prefix . $reference_table;
179 | $this->sql['foreignKey'] = "ADD FOREIGN KEY (`$column`) REFERENCES $table_name (`$reference_column`)" ;
180 | return $this;
181 | }
182 |
183 | public function onDelete(string $action): self
184 | {
185 | $this->sql['onDelete'] = "ON DELETE $action";
186 | return $this;
187 | }
188 |
189 | public function enum(array $allowed): self
190 | {
191 | $list = '';
192 | foreach ($allowed as $value) {
193 | if (gettype($value) === 'string') {
194 | $list .= "'$value', ";
195 | } else {
196 | $list .= $value . ", ";
197 | }
198 | }
199 |
200 | $list = substr(trim($list), 0, -1);
201 |
202 | $this->sql[$this->column_name] .= " ENUM(" . $list . ")";
203 | return $this;
204 | }
205 |
206 | protected function start()
207 | {
208 | $table_name = $this->get_table_name();
209 | $this->sql['start'] = "ALTER TABLE $table_name";
210 | }
211 |
212 | private function get_table_name()
213 | {
214 | return $this->getTablePrefix()->prefix . $this->table_name;
215 | }
216 |
217 | private function getTablePrefix()
218 | {
219 | if (empty(QueryFactory::getConfig())) {
220 | global $wpdb;
221 | return $wpdb;
222 | }
223 | return QueryFactory::getConfig();
224 | }
225 |
226 | private function hasColumn($column)
227 | {
228 | $columns = [];
229 | $driver = $this->db;
230 | $table_name = Utilities::get_db_configs()->prefix .$this->table_name;
231 |
232 | if (class_exists('wpdb') && $driver instanceof \wpdb) {
233 | $columns = $driver->get_results("DESCRIBE `$table_name`", ARRAY_N);
234 | } else {
235 | $columns = $driver->query("DESCRIBE `$table_name`")->fetchAll(\PDO::FETCH_COLUMN);
236 | }
237 |
238 | foreach ($columns as $value) {
239 | if (is_array($value) && $value[0] === $column) {
240 | return $column;
241 | }
242 | if (! is_array($value) && $value === $column) {
243 | return $column;
244 | }
245 | }
246 |
247 | return false;
248 | }
249 |
250 | // get only sql query string
251 | public function getSql()
252 | {
253 | $this->start();
254 | $query = [
255 | 'query' => SqlGenerator::alter($this->sql),
256 | ];
257 | return $query;
258 | }
259 |
260 | private function driver_execute($sql)
261 | {
262 | $driver = $this->db;
263 | if (class_exists('wpdb') && $driver instanceof \wpdb) {
264 | return $driver->query($sql);
265 | }
266 |
267 | try {
268 | return $driver->exec($sql);
269 | } catch (\PDOException $exception) {
270 | Utilities::throughException($exception);
271 | }
272 | }
273 |
274 | public function execute()
275 | {
276 | $this->start();
277 | $query = SqlGenerator::alter($this->sql);
278 |
279 | if ($this->column_exists) {
280 | return;
281 | }
282 |
283 | $this->driver_execute($query);
284 | }
285 | }
286 |
--------------------------------------------------------------------------------
/src/Statement/Create.php:
--------------------------------------------------------------------------------
1 | db = $db;
21 | $this->table_name = $table_name;
22 |
23 | $this->start();
24 | $this->sql['table_name'] = $this->get_table_name();
25 | }
26 |
27 | public function column(string $column_name): self
28 | {
29 | $this->column_name = $column_name;
30 | $this->sql['columns'][$column_name] = [];
31 | return $this;
32 | }
33 |
34 | public function int(int $size = 255): self
35 | {
36 | $this->sql['columns'][$this->column_name]['int'] = "INT($size)";
37 | return $this;
38 | }
39 |
40 | public function bigInt(int $size = 255): self
41 | {
42 | $this->sql['columns'][$this->column_name]['bigInt'] = "BIGINT($size)";
43 | return $this;
44 | }
45 |
46 | public function double(int $size = 255, int $d = 2): self
47 | {
48 | $this->sql['columns'][$this->column_name]['double'] = "DOUBLE($size, $d)";
49 | return $this;
50 | }
51 |
52 | public function boolean(): self
53 | {
54 | $this->sql['columns'][$this->column_name]['boolean'] = "BOOLEAN";
55 | return $this;
56 | }
57 |
58 | public function string(int $size = 255): self
59 | {
60 | $this->sql['columns'][$this->column_name]['string'] = "VARCHAR($size)";
61 | return $this;
62 | }
63 |
64 | public function text(int $size = 10000): self
65 | {
66 | $this->sql['columns'][$this->column_name]['text'] = "TEXT($size)";
67 | return $this;
68 | }
69 |
70 | public function longText(): self
71 | {
72 | $this->sql['columns'][$this->column_name]['longText'] = "LONGTEXT";
73 | return $this;
74 | }
75 |
76 | public function json(): self
77 | {
78 | $this->sql['columns'][$this->column_name]['json'] = "JSON";
79 | return $this;
80 | }
81 |
82 | public function required(): self
83 | {
84 | $this->sql['columns'][$this->column_name]['required'] = "NOT NULL";
85 | return $this;
86 | }
87 |
88 | public function nullable(): self
89 | {
90 | return $this->default('NULL');
91 | }
92 |
93 | public function primary($columns = []): self
94 | {
95 | if (! empty($columns)) {
96 | $this->sql['primary'] = "PRIMARY KEY (" . implode(',', $columns) . ")";
97 | return $this;
98 | }
99 | $this->sql['columns'][$this->column_name]['primary'] = "PRIMARY KEY";
100 | return $this;
101 | }
102 |
103 | public function index(array $columns): self
104 | {
105 | $this->sql['index'] = "INDEX (" . implode(',', $columns) . ")";
106 | return $this;
107 | }
108 |
109 | public function date(): self
110 | {
111 | $this->sql['columns'][$this->column_name]['date'] = "DATE";
112 | return $this;
113 | }
114 |
115 | public function dateTime(): self
116 | {
117 | $this->sql['columns'][$this->column_name]['dateTime'] = "DATETIME";
118 | return $this;
119 | }
120 |
121 | public function timestamp($default = null, $on_update = null): self
122 | {
123 | $this->sql['columns'][$this->column_name]['timestamp'] = "TIMESTAMP";
124 |
125 | if ($default === 'now') {
126 | $this->sql['columns'][$this->column_name]['default'] = "DEFAULT CURRENT_TIMESTAMP";
127 | } elseif ($default && $default !== 'now') {
128 | $this->sql['columns'][$this->column_name]['default'] = "DEFAULT " . $default;
129 | }
130 |
131 | if ($on_update === 'current') {
132 | $this->sql['columns'][$this->column_name]['onUpdate'] = "ON UPDATE CURRENT_TIMESTAMP";
133 | } elseif ($on_update && $on_update !== 'current') {
134 | $this->sql['columns'][$this->column_name]['onUpdate'] = "ON UPDATE " . $on_update;
135 | }
136 |
137 | return $this;
138 | }
139 |
140 | public function unsigned(): self
141 | {
142 | $this->sql['columns'][$this->column_name]['unsigned'] = "UNSIGNED";
143 | return $this;
144 | }
145 |
146 | public function autoIncrement(): self
147 | {
148 | $this->sql['columns'][$this->column_name]['autoIncrement'] = "AUTO_INCREMENT";
149 | return $this;
150 | }
151 |
152 | public function default($value): self
153 | {
154 | $val = is_string($value) ? "'$value'" : $value;
155 | $this->sql['columns'][$this->column_name]['default'] = "DEFAULT $val";
156 | return $this;
157 | }
158 |
159 | public function foreignKey(string $column, string $ref_table_column, string $on_delete = null): self
160 | {
161 | $ref_table_column = explode('.', $ref_table_column);
162 | $table_name = Utilities::get_db_configs()->prefix . $ref_table_column[0];
163 | $this->sql['foreignKey'] = "FOREIGN KEY ($column) REFERENCES $table_name ($ref_table_column[1])";
164 |
165 | if ($on_delete) {
166 | $this->sql['foreignKey'] .= " ON DELETE " . strtoupper($on_delete);
167 | }
168 | return $this;
169 | }
170 |
171 | public function onDelete(string $action): self
172 | {
173 | $this->sql['onDelete'] = "ON DELETE " . strtoupper($action);
174 | return $this;
175 | }
176 |
177 | public function enum(array $allowed): self
178 | {
179 | $list = '';
180 | foreach ($allowed as $value) {
181 | if (gettype($value) === 'string') {
182 | $list .= "'$value', ";
183 | } else {
184 | $list .= $value . ", ";
185 | }
186 | }
187 |
188 | $list = substr(trim($list), 0, -1);
189 |
190 | $this->sql['columns'][$this->column_name]['enum'] = "ENUM(" . $list . ")";
191 | return $this;
192 | }
193 |
194 | protected function start()
195 | {
196 | $this->sql['start'] = 'CREATE TABLE IF NOT EXISTS';
197 | }
198 |
199 | protected function get_table_name()
200 | {
201 | return Utilities::get_db_configs()->prefix . $this->table_name;
202 | }
203 |
204 | // get only sql query string
205 | public function getSql()
206 | {
207 | $this->start();
208 | $query = [
209 | 'query' => SqlGenerator::create($this->sql),
210 | ];
211 | return $query;
212 | }
213 |
214 | private function driver_execute($sql)
215 | {
216 | $driver = $this->db;
217 | if (class_exists('wpdb') && $driver instanceof \wpdb) {
218 | return $driver->query($sql);
219 | }
220 |
221 | try {
222 | return $driver->exec($sql);
223 | } catch (\PDOException $exception) {
224 | Utilities::throughException($exception);
225 | }
226 | }
227 |
228 | public function execute()
229 | {
230 | $this->start();
231 | $query = SqlGenerator::create($this->sql);
232 |
233 | $this->driver_execute($query);
234 | }
235 | }
236 |
--------------------------------------------------------------------------------
/src/Statement/Delete.php:
--------------------------------------------------------------------------------
1 | db = $db;
20 | $this->table_name = Utilities::get_db_configs()->prefix . $table_name;
21 | }
22 |
23 | protected function start()
24 | {
25 | $this->sql['start'] = 'DELETE FROM ' . $this->table_name;
26 | }
27 |
28 | public function where($column, string $operator = null, string $value = null): self
29 | {
30 | if ( is_callable( $column ) ) {
31 | call_user_func( $column, $this );
32 | return $this;
33 | }
34 | $this->sql['where'] = 'WHERE ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
35 | $this->params[] = $value;
36 | return $this;
37 | }
38 |
39 | public function andWhere(string $column, string $operator = null, string $value = null): self
40 | {
41 | $this->sql['andWhere'] = 'AND ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
42 | $this->params[] = $value;
43 | return $this;
44 | }
45 |
46 | public function orWhere(string $column, string $operator = null, string $value = null): self
47 | {
48 | $this->sql['orWhere'] = 'OR ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
49 | $this->params[] = $value;
50 | return $this;
51 | }
52 |
53 | public function drop()
54 | {
55 | $this->sql['drop'] = 'DROP TABLE ' . $this->table_name;
56 | return $this;
57 | }
58 |
59 | public function dropIfExists()
60 | {
61 | $this->sql['drop'] = 'DROP TABLE IF EXISTS ' . $this->table_name;
62 | return $this;
63 | }
64 |
65 | private function driver_exicute($sql)
66 | {
67 | $driver = $this->db;
68 | if (class_exists('wpdb') && $driver instanceof \wpdb) {
69 | return $driver->query($driver->prepare($sql, $this->params));
70 | }
71 |
72 | $data = $driver->prepare($sql);
73 | try {
74 | return $data->execute($this->params);
75 | } catch (\PDOException $exception) {
76 | Utilities::throughException($exception);
77 | }
78 | }
79 |
80 | private function delete_data()
81 | {
82 | $query = SqlGenerator::delete($this->sql);
83 |
84 | return $this->driver_exicute($query);
85 | }
86 |
87 | // get only sql query string
88 | public function getSql()
89 | {
90 | $this->start();
91 | $query = [
92 | 'query' => SqlGenerator::delete($this->sql),
93 | 'params' => $this->params,
94 | ];
95 | return $query;
96 | }
97 |
98 | public function execute()
99 | {
100 | $this->start();
101 | $this->delete_data();
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/Statement/Drop.php:
--------------------------------------------------------------------------------
1 | db = $db;
21 | $this->table_name = Utilities::get_db_configs()->prefix . $table_name;
22 | }
23 |
24 | public function drop()
25 | {
26 | $this->sql['drop'] = 'DROP TABLE ' . $this->table_name;
27 | $this->drop_table();
28 | }
29 |
30 | public function dropIfExists()
31 | {
32 | $this->sql['drop'] = 'DROP TABLE IF EXISTS ' . $this->table_name;
33 | $this->drop_table();
34 | }
35 |
36 | private function driver_execute($sql)
37 | {
38 | $driver = $this->db;
39 | if (class_exists('wpdb') && $driver instanceof \wpdb) {
40 | return $driver->query($sql);
41 | }
42 |
43 | $data = $driver->prepare($sql);
44 | try {
45 | return $data->execute($this->params);
46 | } catch (\Exception $exception) {
47 | Utilities::throughException($exception);
48 | }
49 | }
50 |
51 | private function drop_table()
52 | {
53 | $query = trim($this->sql['drop']);
54 |
55 | $this->driver_execute($query);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Statement/Insert.php:
--------------------------------------------------------------------------------
1 | db = $db;
21 | $this->data = $data;
22 | $this->table_name = $table_name;
23 |
24 | $this->start();
25 | $this->sql['table_name'] = $this->get_table_name();
26 | $this->sql['columns'] = $this->get_columns();
27 | $this->sql['value_placeholders'] = $this->get_value_placeholders();
28 | $this->params = $this->get_params();
29 |
30 | $this->insert_data();
31 | }
32 |
33 | private function insert_data()
34 | {
35 | $query = SqlGenerator::insert($this->sql);
36 |
37 | $this->driver_execute($query);
38 | }
39 |
40 | private function driver_execute($sql)
41 | {
42 | $driver = $this->db;
43 | if (class_exists('wpdb') && $driver instanceof \wpdb) {
44 | return $driver->query($driver->prepare($sql, $this->params));
45 | }
46 |
47 | $data = $driver->prepare($sql);
48 | try {
49 | return $data->execute($this->params);
50 | } catch (\Exception $exception) {
51 | Utilities::throughException($exception);
52 | }
53 | }
54 |
55 | private function start()
56 | {
57 | $this->sql['start'] = 'INSERT INTO';
58 | }
59 |
60 | private function get_table_name()
61 | {
62 | return Utilities::get_db_configs()->prefix . $this->table_name;
63 | }
64 |
65 | private function get_columns()
66 | {
67 | if (empty($this->data)) return;
68 |
69 | $columns = [];
70 | foreach ($this->data[0] as $column => $value) {
71 | $columns[] = $column;
72 | }
73 | return '(' . implode(', ', $columns) . ')';
74 | }
75 |
76 | private function get_value_placeholders()
77 | {
78 | $placeholders = [];
79 |
80 | if (count($this->data) > 1) {
81 | foreach ($this->data as $row) {
82 | $placeholders[] = '(' . implode(',', array_fill(0, count($row), Utilities::get_placeholder($this->db, $row))) . ')';
83 | }
84 | } else {
85 | $placeholders[] = '(' . implode(',', array_fill(0, count($this->data[0]), Utilities::get_placeholder($this->db, $this->data))) . ')';
86 | }
87 | return 'VALUES ' . implode(',', $placeholders);
88 | }
89 |
90 | private function get_params()
91 | {
92 | $params = [];
93 | foreach ($this->data as $value) {
94 | foreach ($value as $val) {
95 | $params[] = $val;
96 | }
97 | }
98 | return $params;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/Statement/Select.php:
--------------------------------------------------------------------------------
1 | db = $db;
22 | }
23 |
24 | protected function start()
25 | {
26 | $this->sql['start']['select'] = 'SELECT';
27 | }
28 |
29 | protected function setStartExpression()
30 | {
31 | $sql = '';
32 | if (isset($this->sql['start']['select'])) {
33 | $sql .= 'SELECT ';
34 | }
35 | if (isset($this->sql['start']['distinct'])) {
36 | $sql .= 'DISTINCT ';
37 | }
38 | if (isset($this->sql['columns'])) {
39 | $sql .= $this->sql['columns'];
40 | unset($this->sql['columns']);
41 | }
42 | if (isset($this->sql['start']['count'])) {
43 | $sql .= ', ' . $this->sql['start']['count'];
44 | }
45 | return $this->sql['start'] = $sql;
46 | }
47 |
48 | public function distinct(): self
49 | {
50 | $this->sql['start']['distinct'] = 'DISTINCT';
51 | return $this;
52 | }
53 |
54 | public function columns(...$columns): self
55 | {
56 | $this->sql['columns'] = implode(', ', $columns);
57 | return $this;
58 | }
59 |
60 | public function alias(string $name): self
61 | {
62 | $this->sql['alias'] = 'AS ' . $name;
63 | return $this;
64 | }
65 |
66 | public function from(string $table_name): self
67 | {
68 | $this->sql['table_name'] = 'FROM ' . Utilities::get_db_configs()->prefix . $table_name;
69 | return $this;
70 | }
71 |
72 | public function where($column, ?string $operator = null, $value = null): self
73 | {
74 | if ( is_callable( $column ) ) {
75 | call_user_func( $column, $this );
76 | return $this;
77 | }
78 | $this->sql['where'] = 'WHERE ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
79 | $this->params[] = $value;
80 | return $this;
81 | }
82 |
83 | public function andWhere(string $column, string $operator = null, $value = null): self
84 | {
85 | $this->sql['andWhere'] = 'AND ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
86 | $this->params[] = $value;
87 | return $this;
88 | }
89 |
90 | public function orWhere(string $column, string $operator = null, $value = null): self
91 | {
92 | $this->sql['orWhere'] = 'OR ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
93 | $this->params[] = $value;
94 | return $this;
95 | }
96 |
97 | public function whereNot(string $column, string $operator = null, $value = null): self
98 | {
99 | $this->sql['whereNot'] = 'WHERE NOT ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
100 | $this->params[] = $value;
101 | return $this;
102 | }
103 |
104 | public function andNot(string $column, string $operator = null, $value = null): self
105 | {
106 | $this->sql['andNot'] = 'AND NOT ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
107 | $this->params[] = $value;
108 | return $this;
109 | }
110 |
111 | public function whereIn(string $column, ...$value): self
112 | {
113 | $this->sql['whereIn'] = 'WHERE ' . $column . ' IN (' . implode( ', ', $value ) . ')';
114 | return $this;
115 | }
116 |
117 | public function orderBy($column, string $sort_type): self
118 | {
119 | $col = is_array( $column ) ? implode( ', ', $column ) : $column;
120 | $this->sql['orderBy'] = 'ORDER BY ' . $col . ' ' . $sort_type;
121 | return $this;
122 | }
123 |
124 | public function groupBy($column): self
125 | {
126 | $col = is_array( $column ) ? implode( ', ', $column ) : $column;
127 | $this->sql['groupBy'] = 'GROUP BY ' . $col;
128 | return $this;
129 | }
130 |
131 | public function limit(int $count): self
132 | {
133 | $this->sql['limit'] = 'LIMIT ' . $count;
134 | return $this;
135 | }
136 |
137 | public function offset(int $count): self
138 | {
139 | $this->sql['offset'] = 'OFFSET ' . $count;
140 | return $this;
141 | }
142 |
143 | public function count(string $column, string $alias = ''): self
144 | {
145 | $alias = $alias ? ' ' . $alias : '';
146 | $this->sql['start']['count'] = 'COUNT(' . $column . ')' . $alias;
147 | return $this;
148 | }
149 |
150 | private function setJoin($table_name, string $col1 = null, string $col2 = null, string $joinType = 'JOIN'): self
151 | {
152 | $table_names = [];
153 | if (is_array($table_name)) {
154 | foreach ($table_name as $table) {
155 | $table_names[] = Utilities::get_db_configs()->prefix . $table;
156 | }
157 | } else {
158 | $table_names[] = Utilities::get_db_configs()->prefix . $table_name;
159 | }
160 |
161 | $table = '';
162 | if (count($table_names) > 1) {
163 | $table = '(' . implode(',', $table_names) . ')';
164 | } else {
165 | $table = $table_names[0];
166 | }
167 |
168 | $this->sql['join'] = $joinType . ' ' . $table;
169 | if ($col1 && $col2) {
170 | $this->sql['join'] .= ' ON ' . $col1 . ' = ' . $col2;
171 | }
172 | return $this;
173 | }
174 |
175 | public function join($table_name, string $col1 = null, string $col2 = null): self
176 | {
177 | return $this->setJoin($table_name, $col1, $col2);
178 | }
179 |
180 | public function innerJoin($table_name, string $col1 = null, string $col2 = null): self
181 | {
182 | return $this->setJoin($table_name, $col1, $col2, 'INNER JOIN');
183 | }
184 |
185 | public function leftJoin($table_name, string $col1 = null, string $col2 = null): self
186 | {
187 | return $this->setJoin($table_name, $col1, $col2, 'LEFT JOIN');
188 | }
189 |
190 | public function rightJoin($table_name, string $col1 = null, string $col2 = null): self
191 | {
192 | return $this->setJoin($table_name, $col1, $col2, 'RIGHT JOIN');
193 | }
194 |
195 | public function raw(string $sql): self
196 | {
197 | $this->sql['raw_'. $this->row_count++] = $sql;
198 | return $this;
199 | }
200 |
201 | protected function setAlias()
202 | {
203 | if (! isset($this->sql['alias'])) return;
204 |
205 | $this->sql['table_name'] .= ' ' . $this->sql['alias'];
206 | unset($this->sql['alias']);
207 | }
208 |
209 | private function fetch($query, array $args = [])
210 | {
211 | try {
212 | return $this->driver_execute($query, $args);
213 | } catch (\Exception $exception) {
214 | Utilities::throughException($exception);
215 | }
216 | }
217 |
218 | private function driver_execute($sql, $placeholders)
219 | {
220 | $driver = $this->db;
221 | if (class_exists('wpdb') && $driver instanceof \wpdb) {
222 | if (empty($placeholders)) {
223 | return $driver->get_results($sql, ARRAY_A);
224 | }
225 |
226 | return $driver->get_results(
227 | $driver->prepare($sql, $placeholders),
228 | ARRAY_A
229 | );
230 | }
231 |
232 | $data = $driver->prepare($sql);
233 | $data->execute($placeholders);
234 | return $data->fetchAll(\PDO::FETCH_ASSOC);
235 | }
236 |
237 | // get only sql query string
238 | public function getSql()
239 | {
240 | $this->start();
241 | $this->setAlias();
242 | $this->setStartExpression();
243 | $query = [
244 | 'query' => SqlGenerator::select($this->sql),
245 | 'params' => $this->params
246 | ];
247 | return $query;
248 | }
249 |
250 | // get data from database
251 | public function get()
252 | {
253 | $this->start();
254 | $this->setAlias();
255 | $this->setStartExpression();
256 | $query = SqlGenerator::select($this->sql);
257 |
258 | $data = $this->fetch($query, $this->params);
259 | return $data;
260 | }
261 | }
262 |
--------------------------------------------------------------------------------
/src/Statement/Update.php:
--------------------------------------------------------------------------------
1 | db = $db;
21 |
22 | $this->data = $data;
23 | $this->table_name = $this->get_table_prefix()->prefix . $table_name;
24 | $this->sql['set_columns'] = $this->set_columns();
25 | }
26 |
27 | private function driver_execute($sql)
28 | {
29 | $driver = $this->db;
30 | if (class_exists('wpdb') && $driver instanceof \wpdb) {
31 | return $driver->query($driver->prepare($sql, $this->params));
32 | }
33 |
34 | $data = $driver->prepare($sql);
35 | try {
36 | return $data->execute($this->params);
37 | } catch (\Exception $exception) {
38 | Utilities::throughException($exception);
39 | }
40 | }
41 |
42 | private function update_data()
43 | {
44 | $query = SqlGenerator::update($this->sql);
45 |
46 | $this->driver_execute($query);
47 | }
48 |
49 | public function execute()
50 | {
51 | $this->start();
52 | $this->update_data();
53 | }
54 |
55 | // get only sql query string
56 | public function getSql()
57 | {
58 | $this->start();
59 | $query = [
60 | 'query' => SqlGenerator::update($this->sql),
61 | 'params' => $this->params,
62 | ];
63 | return $query;
64 | }
65 |
66 | private function get_table_prefix()
67 | {
68 | if (empty(QueryFactory::getConfig())) {
69 | global $wpdb;
70 | return $wpdb;
71 | }
72 | return QueryFactory::getConfig();
73 | }
74 |
75 | protected function start()
76 | {
77 | $this->sql['start'] = 'UPDATE ' . $this->table_name;
78 | }
79 |
80 | protected function set_columns()
81 | {
82 | if (empty($this->data)) return;
83 |
84 | $columns = [];
85 | foreach ($this->data as $column => $value) {
86 | $columns[] = $column . '=' . Utilities::get_placeholder($this->db, $value);
87 | $this->params[] = $value;
88 | }
89 | return 'SET ' . implode(', ', $columns);
90 | }
91 |
92 | public function where($column, string $operator = null, $value = null): self
93 | {
94 | if ( is_callable( $column ) ) {
95 | call_user_func( $column, $this );
96 | return $this;
97 | }
98 | $this->sql['where'] = 'WHERE ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
99 | $this->params[] = $value;
100 | return $this;
101 | }
102 |
103 | public function andWhere(string $column, string $operator = null, $value = null): self
104 | {
105 | $this->sql['andWhere'] = 'AND ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
106 | $this->params[] = $value;
107 | return $this;
108 | }
109 |
110 | public function orWhere(string $column, string $operator = null, $value = null): self
111 | {
112 | $this->sql['orWhere'] = 'OR ' . $column . ' ' . $operator . ' ' . Utilities::get_placeholder($this->db, $value);
113 | $this->params[] = $value;
114 | return $this;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/Utilities.php:
--------------------------------------------------------------------------------
1 | ");
10 | $error_msg = sprintf(
11 | "%s %s",
12 | 'ERROR Message:',
13 | $exception->getMessage()
14 | );
15 | printf($error_msg);
16 | printf("
In %s %s
", $exception->getFile(), $exception->getLine());
17 | printf(
18 | "
",
19 | print_r($exception->getTrace(), true)
20 | );
21 | printf("");
22 |
23 | throw new \Exception($exception->getMessage());
24 | }
25 |
26 | public static function get_placeholder($db, $value)
27 | {
28 | if ($db instanceof \wpdb) {
29 | if (is_array($value)) return '%s';
30 | if (is_string($value)) return '%s';
31 | if (is_integer($value)) return '%d';
32 | if (is_float($value)) return '%f';
33 | }
34 | return "?";
35 | }
36 |
37 | public static function get_db_configs()
38 | {
39 | if (empty(QueryFactory::getConfig())) {
40 | global $wpdb;
41 | return $wpdb;
42 | }
43 | return QueryFactory::getConfig();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tests/CreateTest.php:
--------------------------------------------------------------------------------
1 | column('ID')->bigInt()->unsigned()->autoIncrement()->primary()->required()
16 | ->column('name')->string(255)->required()
17 | ->column('email')->string(255)->default('nil')
18 | ->index(['ID'])
19 | ->getSql();
20 |
21 | $this->assertSame($sql, $query);
22 | }
23 |
24 | public function test_nullable()
25 | {
26 | $sql = "CREATE TABLE IF NOT EXISTS wp_test (secondary_email VARCHAR(255) DEFAULT 'NULL')";
27 |
28 | $query = CreateApi::create('test')
29 | ->column('secondary_email')->string(255)->default('NULL')
30 | ->getSql();
31 |
32 | $this->assertSame($sql, $query);
33 |
34 | $query = CreateApi::create('test')
35 | ->column('secondary_email')->string(255)->nullable()
36 | ->getSql();
37 |
38 | $this->assertSame($sql, $query);
39 |
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tests/SelectTest.php:
--------------------------------------------------------------------------------
1 | from('posts')
16 | ->getSql();
17 |
18 | $this->assertSame($sql, $query);
19 | }
20 |
21 | public function testDistinct()
22 | {
23 | $sql = 'SELECT DISTINCT * FROM wp_posts';
24 | $query =
25 | SelectApi::select('*')
26 | ->distinct()
27 | ->from('posts')
28 | ->getSql();
29 |
30 | $this->assertSame($sql, $query);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/Statement/CreateApi.php:
--------------------------------------------------------------------------------
1 | db = $db;
14 | $this->table_name = $table_name;
15 | $this->wpdb_object = new \stdClass;
16 | $this->wpdb_object->prefix = 'wp_';
17 |
18 | $this->start();
19 | $this->sql['table_name'] = $this->get_table_name();
20 | }
21 |
22 | public static function create($table_name)
23 | {
24 | $driver = new \stdClass;
25 | $create = new self($driver, $table_name);
26 | return $create;
27 | }
28 |
29 | public function getSql()
30 | {
31 | $this->start();
32 | $query = SqlGenerator::create($this->sql);
33 |
34 | return $query;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tests/Statement/SelectApi.php:
--------------------------------------------------------------------------------
1 | db = $db;
14 | $this->wpdb_object = new \stdClass;
15 | $this->wpdb_object->prefix = 'wp_';
16 | }
17 |
18 | public static function select($colmns)
19 | {
20 | $driver = new \stdClass;
21 | $select = new self($driver);
22 | $select->columns($colmns);
23 | return $select;
24 | }
25 |
26 | public function getSql()
27 | {
28 | $this->start();
29 | $this->setAlias();
30 | $this->setStartExpression();
31 | $query = SqlGenerator::select($this->sql);
32 |
33 | return $query;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/Statement/UpdateApi.php:
--------------------------------------------------------------------------------
1 | db = $db;
13 | $this->data = $data;
14 | $this->wpdb_object = new \stdClass;
15 |
16 | $this->table_name = 'wp_' . $table_name;
17 | $this->sql['set_columns'] = $this->set_columns();
18 | }
19 |
20 | public static function update(string $table_name, array $data)
21 | {
22 | $driver = new \stdClass;
23 | $update = new self($driver, $table_name, $data);
24 | return $update;
25 | }
26 |
27 | public function getSql()
28 | {
29 | $this->start();
30 | $query = SqlGenerator::update($this->sql);
31 |
32 | return $query;
33 | }
34 |
35 | public function getParams()
36 | {
37 | return $this->params;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/UpdateTest.php:
--------------------------------------------------------------------------------
1 | 'Keramot UL',
16 | 'email' => 'keramotul.islam@gmail.com'
17 | ])
18 | ->getSql();
19 |
20 | $this->assertEquals($sql, $query);
21 | }
22 |
23 | public function testWhere()
24 | {
25 | $sql = 'UPDATE wp_querybuilders SET name=?, email=? WHERE ID = ?';
26 | $query =
27 | UpdateApi::update('querybuilders', [
28 | 'name' => 'Keramot UL',
29 | 'email' => 'keramotul.islam@gmail.com'
30 | ])
31 | ->where('ID', '=', 1)
32 | ->getSql();
33 |
34 | $this->assertEquals($sql, $query);
35 | }
36 |
37 | public function testParams()
38 | {
39 | $params = ['Keramot UL', 'keramotul.islam@gmail.com', 1];
40 | $query =
41 | UpdateApi::update('querybuilders', [
42 | 'name' => 'Keramot UL',
43 | 'email' => 'keramotul.islam@gmail.com'
44 | ])
45 | ->where('ID', '=', 1)
46 | ->getParams();
47 |
48 | $this->assertEquals($params, $query);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------