module DBX

Overview

DBX is a helper to handle multi DBs using the compatible drivers with the common crystal-db module.

Example with PostgreSQL:

# Connection URI / DSL https://www.postgresql.org/docs/current/libpq-connect.html#h5o-9
db = DBX.open("app", "postgres://...", true)

pp DBX.db?("app") ? "defined" : "not defined"

db.query "select id, created_at, email from users" do |rs|
  rs.each do
    id = rs.read(Int32)
    created_at = rs.read(Time)
    email = rs.read(String)
    puts "##{id}: #{email} #{created_at}"
  end
end

# Closes all connections of this DB connection pool and remove this DB connection pool.
DBX.destroy("app")

Model:

class User
  include DBX::ORM::DSL

  field lang : String

  @[JSON::Field(key: "firstName")]
  field first_name : String?
end

db = DBX.open "app", App.cfg.db_uri

user = User.from_rs(db.query("SELECT id, lang, first_name FROM users"))
pp user.to_json

user = User.from_json "{\"lang\":\"fr\",\"firstName\":\"Nico\"}"
pp user

See also DBX::ORM for a more advanced model system and query builder.

Resources:

Defined in:

dbx.cr
query_builder/builder.cr
query_builder/builder_criteria.cr
query_builder/builder_support.cr
query_builder/executor.cr
query_builder/scope.cr

Constant Summary

VERSION = {{ (`shards version \"/media/data/lab/dev/work/projects/nicolab/crystal/crystal-dbx/src\"`).chomp.stringify.downcase }}

Class Method Summary

Macro Summary

Class Method Detail

def self.db(name : String, uri : String, strict = false) : DB::Database #

Same as .open.


def self.db(name : String) : DB::Database #

Uses a given DB connection pool.


def self.db?(name : String) : Bool #

Checks that a DB connection pool exists.


def self.dbs : DBHashType #

Returns all DB::Database instances.


def self.destroy(name : String) #

Closes all connections of the DB connection pool name and remove the name DB connection pool.


def self.destroy : Tuple(Int32, Int32) #

Destroy all DB connection pool and and their connections.


def self.open(name : String, uri : String, strict = false) : DB::Database #

Ensures only once DB connection pool by name is open. If the DB connection pool name is already initialized, it is returned. Raises an error if strict is true and the DB connection pool name is already opened.


def self.pool_open_connections(name : String) : Int32 #

Gets the number of the connections opened in the pool of name.


def self.pool_stats(name : String) : DB::Pool::Stats? #

Pool stats https://crystal-lang.github.io/crystal-db/api/latest/DB/Pool.html


Macro Detail

macro around_query_or_exec(&block) #

This macro allows injecting code to be run before and after the execution of the request. It should return the yielded value. It must be called with 1 block argument that will be used to pass the args : Enumerable. This macro should be called at the top level, not from a method.

Be careful of the performance penalty that each hook may cause, be aware that your code will be executed at each query and exec.
DBX.around_query_or_exec do |args|
  puts "before"
  res = yield
  puts "after"

  puts res.class
  puts "exec" if res.is_a?(DB::ExecResult)
  puts "query" if res.is_a?(DB::ResultSet)

  puts "with args:"
  pp args

  res
end

Example to measure query execution time:

DBX.around_query_or_exec do |args|
  start = Time.monotonic
  res = yield
  elapsed_time = Time.monotonic - start

  puts "Query execution time: #{elapsed_time}"
  res
end