GithubHelp home page GithubHelp logo

sqlmethods's Introduction

SQLMethods

Lightweight PHP class with no dependencies to dynamically define methods as queries in SQL files.
Clean separation of concerns inspired by this 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.

-- SQLMethods example SQL file

-- Query definition header format:
-- Single line starts with --! followed by metadata in JSON
-- Metadata JSON format: {"name":<query name>, "param_mode":<parameters mode> [,"returns_value":<return mode>]}
-- <query name> is a valid K&R indentifier string that becomes a method name;
-- <parameters mode> is one of "NONE", "NAMED" or "POSITIONAL"
-- <return mode> (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 object (resultset).
  • If "returns_value" is true then the methods retun a single value by invoking fetchColumn() on the resultset.
  • This JSON schema contains a strict definition.

SQLMethods constructor

A SQLMethods object is created by instantiating the SQLMethods class.
SQLMethods::__construct(optional <sql file name>, optional <PDO connection>)

  • <sql file name> - name of the SQL file (as the one above)
  • <PDO connection> - existing PDO connection object

SQLMethods instance factory

Static method. Creates and returns a SQLMethods instance object that can be chained.
SQLMethods::createInstance(optional <PDO connection>)

  • <PDO connection> - existing PDO connection object

Connection setter

Sets the PDO connection
SQLMethods::connection(<PDO connection>)

  • <PDO connection> - existing PDO connection object
  • returns the object instance that can be chained

SQL file importer

Parses and imports SQL method definitions.
SQLMethods::import(<filename>)

  • <filename> - existing SQL file
  • returns the object instance that can be chained

Usage example (PHP CLI) in file example.php

This particular example uses PostgreSQL PDO connection.

<?php
// SQLMethods example/unit test

// Use your preferred class loading mechanism
require ('SQLMethods.class.php');

// Obtain a PDO connection in your preferred way
$conn = new PDO (
    'pgsql:host=<host>;port=<port>;dbname=<database name>',
    '<user>', '<password>',
    [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.

$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

sqlmethods's People

Contributors

stefanov-sm avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.