https://github.com/stefanov-sm/sqlmethods
Define PHP methods as SQL queries
https://github.com/stefanov-sm/sqlmethods
php postgresql sql
Last synced: 12 months ago
JSON representation
Define PHP methods as SQL queries
- Host: GitHub
- URL: https://github.com/stefanov-sm/sqlmethods
- Owner: stefanov-sm
- License: mit
- Created: 2019-09-29T19:20:53.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2020-02-18T10:20:23.000Z (about 6 years ago)
- Last Synced: 2025-02-15T23:42:24.731Z (about 1 year ago)
- Topics: php, postgresql, sql
- Language: PHP
- Homepage:
- Size: 151 KB
- Stars: 1
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# SQLMethods
Lightweight PHP class with no dependencies to dynamically define methods as queries in SQL files.
Clean separation of concerns inspired by [this](https://www.youtube.com/watch?v=q9IXCdy_mtY) talk and **YeSQL**.
All that matters is there in the PHP CLI example.
### File _example.sql_ - the queries that become methods
Individual queries have names (Ruffus, Buster, Gracie, ISOTime in the example below) that become methods' names.
```SQL
-- SQLMethods example SQL file
-- Query definition header format:
-- Single line starts with --! followed by metadata in JSON
-- Metadata JSON format: {"name":, "param_mode": [,"returns_value":]}
-- is a valid K&R indentifier string that becomes a method name;
-- is one of "NONE", "NAMED" or "POSITIONAL"
-- (optional) is true or false (default)
-- See the example below
-- No parameters
--! {"name":"RUFFUS", "param_mode":"NONE"}
SELECT v, to_char(123 + v, 'FMRN')
FROM generate_series (10, 12, 1) t(v);
-- Named parameters
--! {"name":"Buster", "param_mode":"NAMED"}
SELECT v, to_char(234 + v, 'FMRN')
FROM generate_series (:lo, :hi, 1) t(v);
-- Positional parameters
--! {"name":"Gracie", "param_mode":"POSITIONAL"}
SELECT v, to_char(345 + v, 'FMRN')
FROM generate_series (?, ?, 1) t(v);
-- Positional parameters, returns a single value
--! {"name":"ISOTime", "param_mode":"POSITIONAL", "returns_value": true}
SELECT to_char(now() - ?::interval, 'YYYY-MM-DD"T"HH24:MI:SS');
```
- Note these query definition header lines that provide a name and parameters' mode value to each query:
```
--! {"name":"RUFFUS", "param_mode":"NONE"}
--! {"name":"Buster", "param_mode":"NAMED"}
--! {"name":"Gracie", "param_mode":"POSITIONAL"}
--! {"name":"ISOTime", "param_mode":"POSITIONAL", "returns_value": true}
```
- Each query definition header consists of a single line that starts with `--!` prefix followed by a JSON expression with these mandatory attributes: `"name"`, `"param_mode"` and an optional one `"returns_value"`.
- The value of "param_mode" must be one of `"NONE"`, `"NAMED"` or `"POSITIONAL"`. The semantics of those are best seen in the example.
- The value of "name" must be a valid K&R-style identifier.
- The value of "returns_value" must be `true` or `false` (default).
- Real-life queries may be of any size and complexity.
- Block comments are not supported.
- If "returns_value" is missing or false then the methods return a [PDOStatement](https://www.php.net/manual/en/class.pdostatement.php) object (resultset).
- If "returns_value" is true then the methods retun a single value by invoking `fetchColumn()` on the resultset.
- [This](https://github.com/stefanov-sm/SQLMethods/blob/master/query.header.schema.json) JSON schema contains a strict definition.
### SQLMethods constructor
A SQLMethods object is created by instantiating the SQLMethods class.
`SQLMethods::__construct(optional , optional )`
- `` - name of the SQL file (as the one above)
- `` - existing PDO connection object
### SQLMethods instance factory
Static method. Creates and returns a SQLMethods instance object that can be chained.
`SQLMethods::createInstance(optional )`
- `` - existing PDO connection object
### Connection setter
Sets the PDO connection
`SQLMethods::connection()`
- `` - existing PDO connection object
- returns the object instance that can be chained
### SQL file importer
Parses and imports SQL method definitions.
`SQLMethods::import()`
- `` - existing SQL file
- returns the object instance that can be chained
### Usage example (PHP CLI) in file _example.php_
This particular example uses [PostgreSQL](https://www.postgresql.org/) PDO connection.
```PHP
;port=;dbname=',
'', '',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_EMULATE_PREPARES => FALSE]
);
/* There are different ways to build SQLMethod instances and inport SQL files
// Use a single SQL file
$dbgw = new SQLMethods('sql/example.sql', $conn);
// Use many SQL files
$dbgw = new SQLMethods;
$dbgw -> connection($conn);
$dbgw -> import('sql/none.sql');
$dbgw -> import('sql/named.sql');
$dbgw -> import('sql/positional.sql');
$dbgw -> import('sql/value.sql');
*/
// Use many SQL files w/ method chaining
$dbgw = SQLMethods::createInstance($conn)
-> import('sql/none.sql')
-> import('sql/named.sql')
-> import('sql/positional.sql')
-> import('sql/value.sql');
// call a method with no arguments
$result = $dbgw -> Ruffus();
echo SQLMethods::dump_rs($result);
echo PHP_EOL.PHP_EOL;
// call a method with named arguments
$result = $dbgw -> Buster([':hi' => 17, ':lo' => 15]);
echo SQLMethods::dump_rs($result);
echo PHP_EOL.PHP_EOL;
// call a method with positional arguments
$result = $dbgw -> Gracie(18, 20);
echo SQLMethods::dump_rs($result);
echo PHP_EOL.PHP_EOL;
// call a method with positional arguments that returns a single value
$result = $dbgw -> ISOTime('2 days');
echo $result;
echo PHP_EOL.PHP_EOL;
```
Query names have become method names.
Query/method names and `param_mode` values are case-insensitive as it is common in SQL.
```PHP
$result = $dbgw -> Ruffus();
$result = $dbgw -> Buster([':hi' => 17, ':lo' => 15]);
$result = $dbgw -> Gracie(18, 20);
$result = $dbgw -> ISOTime('2 days');
```
And here is the modest result.
```
C:\ ... \SQLMethods>php example.php
v: 10
rn: CXXXIII
v: 11
rn: CXXXIV
v: 12
rn: CXXXV
v: 15
rn: CCXLIX
v: 16
rn: CCL
v: 17
rn: CCLI
v: 18
rn: CCCLXIII
v: 19
rn: CCCLXIV
v: 20
rn: CCCLXV
2019-12-21T23:42:54
```