module DB
Overview
The DB module is a unified interface to database access. Database dialects is supported by custom database driver shards. Check crystal-lang/crystal-sqlite3 for example.
Drivers implementors check Driver class.
DB manage a connection pool. The connection pool can be configured by URI query. See Database.
Usage
Assuming crystal-sqlite3 is included a sqlite3 database can be opened with #open.
db = DB.open "sqlite3:./path/to/db/file.db"
db.close
If a block is given to #open the database is closed automatically
DB.open "sqlite3:./file.db" do |db|
# work with db
end # db is closed
In the code above db is a Database. Methods available for querying it are described in QueryMethods.
Three kind of statements can be performed:
Database#execwaits no response from the database.Database#scalarreads a single value of the response.Database#queryreturns a ResultSet that allows iteration over the rows in the response and column information.
All of the above methods allows parametrised query. Either positional or named arguments.
Check a full working version:
require "db"
require "sqlite3"
DB.open "sqlite3:./file.db" do |db|
db.exec "create table contacts (name text, age integer)"
db.exec "insert into contacts values (?, ?)", "John Doe", 30
args = [] of DB::Any
args << "Sarah"
args << 33
db.exec "insert into contacts values (?, ?)", args
puts "max age:"
puts db.scalar "select max(age) from contacts" # => 33
puts "contacts:"
db.query "select name, age from contacts order by age desc" do |rs|
puts "#{rs.column_name(0)} (#{rs.column_name(1)})"
# => name (age)
rs.each do
puts "#{rs.read(String)} (#{rs.read(Int32)})"
# => Sarah (33)
# => John Doe (30)
end
end
end
Defined in:
db.crdb/pool.cr
db/string_key_cache.cr
db/query_methods.cr
db/session_methods.cr
db/disposable.cr
db/driver.cr
db/statement.cr
db/begin_transaction.cr
db/connection_context.cr
db/connection.cr
db/transaction.cr
db/pool_statement.cr
db/database.cr
db/pool_prepared_statement.cr
db/pool_unprepared_statement.cr
db/result_set.cr
db/error.cr
db/mapping.cr
spec.cr
db/version.cr
Constant Summary
-
TYPES =
[Nil, String, Bool, Int32, Int64, Float32, Float64, Time, Bytes] -
Types supported to interface with database driver. These can be used in any
ResultSet#reador anyDatabase#queryrelated method to be used as query parameters -
VERSION =
"0.4.4"
Class Method Summary
-
.connect(uri : URI | String)
Opens a connection using the specified uri.
-
.connect(uri : URI | String, &block)
Opens a connection using the specified uri.
-
.open(uri : URI | String)
Opens a database using the specified uri.
-
.open(uri : URI | String, &block)
Same as
#openbut the database is yielded and closed automatically. -
.register_driver(driver_name, driver_class : Driver.class)
Registers a driver class for a given driver_name.
Macro Summary
-
mapping(properties, strict = true)
The
DB.mappingmacro defines how an object is built from a DB::ResultSet. - mapping
Class Method Detail
Opens a connection using the specified uri.
The scheme of the uri determines the driver to use.
Returned connection must be closed by Connection#close.
If a block is used the connection is yielded and closed automatically.
Opens a connection using the specified uri.
The scheme of the uri determines the driver to use.
Returned connection must be closed by Connection#close.
If a block is used the connection is yielded and closed automatically.
Opens a database using the specified uri.
The scheme of the uri determines the driver to use.
Returned database must be closed by Database#close.
If a block is used the database is yielded and closed automatically.
Same as #open but the database is yielded and closed automatically.
Registers a driver class for a given driver_name. Should be called by drivers implementors only.
Macro Detail
The DB.mapping macro defines how an object is built from a DB::ResultSet.
It takes hash literal as argument, in which attributes and types are defined.
Once defined, DB::ResultSet#read(t) populates properties of the class from the
result set.
require "db"
class Employee
DB.mapping({
title: String,
name: String,
})
end
employees = Employee.from_rs(db.query("SELECT title, name FROM employees"))
employees[0].title # => "Manager"
employees[0].name # => "John"
Attributes not mapped with DB.mapping are not defined as properties.
Also, missing attributes raise a DB::Exception.
You can also define attributes for each property.
class Employee
DB.mapping({
title: String,
name: {
type: String,
nilable: true,
key: "firstname",
},
})
end
Available attributes:
- type (required) defines its type. In the example above, title: String is a shortcut to title: {type: String}.
- nilable defines if a property can be a
Nil. - default: value to use if the property is missing in the result set, or if it's
nullandnilablewas not set totrue. If the default value creates a new instance of an object (for example[1, 2, 3]orSomeObject.new), a different instance will be used each time a row is parsed. - key defines which column to read from a reusltset. It defaults to the name of the property.
- converter takes an alternate type for parsing. It requires a
#from_rsmethod in that class, and returns an instance of the given type.
The mapping also automatically defines Crystal properties (getters and setters) for each of the keys. It doesn't define a constructor accepting those arguments, but you can provide an overload.
The macro basically defines a constructor accepting a DB::ResultSet that reads from
it and initializes this type's instance variables.
This macro also declares instance variables of the types given in the mapping.