module Clear::SQL

Overview

Clear::SQL

Clear is made like an onion:

+------------------------------------+
|           THE ORM STACK            +
+------------------------------------+
|  Model | DB Views | Migrations     | < High Level Tools
+---------------+--------------------+
|  Columns | Validation | Converters | < Mapping system
+---------------+--------------------+
|  Clear::SQL   | Clear::Expression  | < Low Level SQL Builder
+------------------------------------+
|  Crystal DB   | Crystal PG         | < Low Level connection
+------------------------------------+

On the bottom stack, Clear offer SQL query building. Theses features are then used by top level parts of the engine.

The SQL module provide a simple API to generate #delete, #insert, #select and #update methods.

Each requests can be duplicated then modified and executed.

Note: Each request object is mutable. Therefore, to update and store a request, you must use manually the dup method.

Included Modules

Extended Modules

Defined in:

clear/sql/connection_pool.cr
clear/sql/errors.cr
clear/sql/fragment/column.cr
clear/sql/fragment/fragment.cr
clear/sql/fragment/from.cr
clear/sql/fragment/join.cr
clear/sql/lock.cr
clear/sql/query/connection.cr
clear/sql/query/from.cr
clear/sql/sql.cr

Class Method Summary

Instance Method Summary

Instance methods inherited from module Clear::SQL::Logger

log_query(sql, &) log_query

Class methods inherited from module Clear::SQL::Logger

colorize : Bool colorize, colorize=(colorize : Bool) colorize=, colorize_query(qry : String) colorize_query, display_mn_sec(x) : String display_mn_sec, display_time(x) : String display_time

Class Method Detail

def self.lock(table : String | Symbol, mode = "ACCESS EXCLUSIVE", connection = "default", &) #

Tablewise locking


[View source]
def self.truncate(tablename : T.class | String, restart_sequence = false, cascade = false, truncate_inherited = true, connection_name : String | Nil = nil) forall T #

Truncate a table or a model

User.query.count          # => 200
Clear::SQL.truncate(User) # equivalent to Clear::SQL.truncate(User.table, connection_name: User.connection)
User.query.count          # => 0

SEE https://www.postgresql.org/docs/current/sql-truncate.html for more information.

  • restart_sequence set to true will append RESTART IDENTITY to the query
  • cascade set to true will append CASCADE to the query
  • truncate_inherited set to false will append ONLY to the query
  • connection_name will be: Model.connection or default unless optionally defined.

[View source]

Instance Method Detail

def add_connection(name : String, url : String, connection_pool_size = 5) #

[View source]
def delete(table : Symbolic) #

Start a DELETE table query


[View source]
def escape(x : String | Symbol) #

Escape the expression, double quoting it.

It allows use of reserved keywords as table or column name

NOTE Escape is used for escaping postgresql keyword. For example if you have a column named order (which is a reserved word), you want to escape it by double-quoting it.

For escaping STRING value, please use Clear::SQL.sanitize


[View source]
def execute(connection_name : String, sql) #

Execute a SQL statement on a specific connection.

Usage: Clear::SQL.execute("seconddatabase", "SELECT 1 FROM users")


[View source]
def execute(sql) #

Execute a SQL statement.

Usage: Clear::SQL.execute("SELECT 1 FROM users")


[View source]
def init(name : String, url : String, connection_pool_size = 5) #

[View source]
def init(url : String, connection_pool_size = 5) #

[View source]
def init(connections : Hash(Symbolic, String), connection_pool_size = 5) #

[View source]
def insert(table, args : NamedTuple) #

[View source]
def insert(table, *args) #

Alias of #insert_into, for hurry developers


[View source]
def insert #

Create a new INSERT query


[View source]
def insert_into(table) #

Start an INSERT INTO table query


[View source]
def insert_into(table, *args) #

Start an INSERT INTO table query

Clear::SQL.insert_into("table", id: 1, name: "hello")

[View source]
def raw(x, *params) #

This provide a fast way to create SQL fragment while escaping items, both with ? and :key system:

query = Mode.query.select(Clear::SQL.raw("CASE WHEN x=:x THEN 1 ELSE 0 END as check", x: "blabla"))
query = Mode.query.select(Clear::SQL.raw("CASE WHEN x=? THEN 1 ELSE 0 END as check", "blabla"))

[View source]
def raw(__template, **params) #

[View source]
def raw_enum(x, params : Enumerable(T)) forall T #

See self.raw Can pass an array to this version


[View source]
def rollback #

Raise a rollback, in case of transaction


[View source]
def sanitize(x) #

Sanitize string and convert some literals (e.g. Time)


[View source]
def select(*args) #

Start a SELECT FROM table query


[View source]
def transaction(connection = "default", &) #

Create an unstackable transaction

Example:

Clear::SQL.transaction do
  # do something
  Clear::SQL.transaction do # Technically, this block do nothing, since we already are in transaction
    rollback                # < Rollback the up-most `transaction` block.
  end
end

see #with_savepoint to use a stackable version using savepoints.


[View source]
def unsafe(x) #

[View source]
def update(table) #

Start a UPDATE table query


[View source]
def with_savepoint(connection_name = "default", &) #

Create a transaction, but this one is stackable using savepoints.

Example:

Clear::SQL.with_savepoint do
  # do something
  Clear::SQL.with_savepoint do
    rollback # < Rollback only the last `with_savepoint` block
  end
end

[View source]