Stored SQL

You'll write .sql files in your BigDb app's sql/ dir. These get compiled and serialized into sql/queries for faster loading at runtime, then executed by file_name.query_name.

Docs

  • Sample Structure
  • Sample Stored create.sql
  • Paramater Binding
  • Naming Queries
  • Sample Stored article.sql (with paramater binding example)

Sample Structure

You can name your .sql files however you like. Below is merely a suggestion.

db/
    migrate/ ...
    orm/ ...
    sql/
        create.sql  -- For your CREATE TABLE and other statements only used during initialization/migrations.
        main.sql    -- For commonly used or otherwise unorganized queries
        blog.sql    -- For queries relating to the 'blog' table

Tip: To keep SQL versioned for migrations, create an sqlv1 dir, and call $db->addSqlDir(...) during migrate/v1/up.php.

Sample Stored create.sql

create.sql:

-- @query(article, -- END) 
DROP TABLE IF EXISTS `article`;
CREATE TABLE IF NOT EXISTS `article` (
    `id` int(11) PRIMARY KEY,
    `title` varchar(256),
    `description` TEXT,
    `slug` varchar(256),
    `created_at` datetime, 
    `status` varchar(30),
    `related_article_id` int(11)
) ; 
-- END

-- @query(author, -- END) 
DROP TABLE IF EXISTS `author`;
CREATE TABLE IF NOT EXISTS `author` (
    `id` int(11) PRIMARY KEY,
    `name` varchar(256),
    `description` TEXT,
    `slug` varchar(256),
    `created_at` datetime, 
    `status` varchar(30)
) ; 
-- END

Paramater Binding

Stored queries can have bindable paramaters.

WARNING: Neither uses the built-in binding feature on PDO, and should be used with caution.

  • :name: The passed-in value is PDO::quote()ed and :name is replaced with the quoted value.
  • {$name}: The passed-in value replaces {$name} as-is, without any PDO::quote()

Naming Queries

For @query(get_books_by_author) in file main.sql, the query's name is main.get_books_by_author.

A stored statement begins with:

-- @query(name, -- delimiter)

The SQL statement starts on the -- @query(...) line and ends on the -- delimiter line. The delimiter should start with -- because this denotes a comment in mysql.

If you do not include a delimiter, then a semicolon (;) is used:

-- @query(name)

The delimiter is needed if there are multiple sql statements, but I like to use it on most named queries, especially if they're more than one line.

Sample Stored article.sql

article.sql: (Notice :status and {$where_clause}. See 'Parmater Binding' above.)

-- @query(sample_data, -- END)
INSERT INTO `article` (`id`, `title`, `description`, `slug`, `created_at`, `status`, `related_article_id`)
    VALUES
    (1, 'One', 'Desc 1', 'one', CURRENT_TIMESTAMP, 'public', NULL),
    (2, 'Two', 'Desc 2', 'two', CURRENT_TIMESTAMP, 'public', NULL),
    (3, 'Three', 'Desc 3', 'three', CURRENT_TIMESTAMP, 'public', 1),
    (4, 'Four, Private', 'Desc 4', 'four-private', CURRENT_TIMESTAMP, 'private', 1)
;
-- END

-- @query(get_public)
SELECT * FROM `article` WHERE `status` LIKE 'public';

-- @query(get_private)
SELECT * FROM `article` WHERE `status` LIKE 'private';

-- @query(get_where)
SELECT * FROM `article` WHERE `status` LIKE :status;

-- @query(insert_with_status, -- END)
INSERT INTO `article` (`id`, `title`, `description`, `slug`, `created_at`, `status`, `related_article_id`)
    VALUES
    (5, 'Status', 'Status 1', 'status', CURRENT_TIMESTAMP, :status, NULL)
;
-- END

-- @query(get_where_clause)
SELECT * FROM `article` {$where_clause};