The Chicago Boss API is mostly stable, but still might change before 1.0.
BossDB is a database abstraction layer used for querying and updating the database. Currently Tokyo Tyrant, Mnesia, MySQL, and PostgreSQL are supported.
Functions in the boss_db
module include:
Apply migrations from list [{Tag, Fun}] currently runs all migrations 'up'
Run database migration {Tag, Fun} in Direction
Find a BossRecord with the specified Id
(e.g. "employee-42") or a value described
by a dot-separated path (e.g. "employee-42.manager.name").
Query for BossRecords. Returns BossRecords of type
Type
matching all of the given Conditions
. Options may include
limit
(maximum number of records to return), offset
(number of records
to skip), order_by
(attribute to sort on), descending
(whether to
sort the values from highest to lowest), and include
(list of belongs_to
associations to pre-cache)
Query for the first BossRecord of type Type
.
Query for the first BossRecord of type Type
matching all of the given Conditions
Query for the first BossRecord of type Type
matching all of the given Conditions
,
sorted on the attribute Sort
.
Query for the last BossRecord of type Type
.
Query for the last BossRecord of type Type
matching all of the given Conditions
Query for the last BossRecord of type Type
matching all of the given Conditions
Count the number of BossRecords of type Type
in the database.
Count the number of BossRecords of type Type
in the database matching
all of the given Conditions
.
Treat the record associated with Id
as a counter and return its value.
Returns 0 if the record does not exist, so to reset a counter just use
"delete".
Treat the record associated with Id
as a counter and atomically increment its value by 1.
Treat the record associated with Id
as a counter and atomically increment its value by Increment
.
Delete the BossRecord with the given Id
.
Create a table based on TableDefinition
Execute raw database commands on SQL databases
Execute database commands with interpolated parameters on SQL databases
Execute a fun inside a transaction.
Save (that is, create or update) the given BossRecord in the database.
Performs validation first; see validate_record/1
.
Validate the given BossRecord without saving it in the database.
ErrorMessages
are generated from the list of tests returned by the BossRecord's
validation_tests/0
function (if defined). The returned list should consist of
{TestFunction, ErrorMessage}
tuples, where TestFunction
is a fun of arity 0
that returns true
if the record is valid or false
if it is invalid.
ErrorMessage
should be a (constant) string which will be included in ErrorMessages
if the TestFunction
returns false
on this particular BossRecord.
Validate the given BossRecord without saving it in the database.
ErrorMessages
are generated from the list of tests returned by the BossRecord's
validation_tests/1
function (if defined), where parameter is atom() on_create | on_update
.
The returned list should consist of {TestFunction, ErrorMessage}
tuples,
where TestFunction
is a fun of arity 0
that returns true
if the record is valid or false
if it is invalid.
ErrorMessage
should be a (constant) string which will be included in ErrorMessages
if the TestFunction
returns false
on this particular BossRecord.
Validate the parameter types of the given BossRecord without saving it to the database.
Returns the type of the BossRecord with Id
, or undefined
if the record does not exist.
If your project is anything like mine then you will probably have a case where you get a JSON in from the user or an api and you want to convert it to a model. we have a new function boss_record:new_from_json/2 which lets you do that automaticly. To run this call new_from_json/2 with your model (atom) and your json record. Note that if you have a field called 'id' you will have to rename or remove it
The "find" and "count" functions each take a set of Conditions
, which specify search criteria. Similar to Microsoft's LINQ, the Conditions
can use a special non-Erlang syntax for conciseness. This special syntax can't be compiled with Erlang's default compiler, so you'll have to let Boss compile your controllers which use it.
Conditions
looks like a list, but each element in the list uses a notation very similar to abstract mathematical notation with a left-hand side (an atom corresponding to a record attribute), a single-character operator, and a right-hand side (values to match to the attribute). The mathematical operators are not all ASCII! You may want to copy-paste the UTF-8 operators below. As an alternative, you can also specify each condition with a 3-tuple with easier-to-type operator names.
As a quick example, to count the number of people younger than 25 with occupation listed as "student" or "unemployed", you would use:
boss_db:count(person, [age < 25, occupation ∈ ["student", "unemployed"]]).
This could also be written:
boss_db:count(person, [{age, 'lt', 25}, {occupation, 'in', ["student", "unemployed"]}]).
Conditions
key = Value
{key, 'equals', Value}
The "key
" attribute is exactly equal to Value
.
key ≠ Value
{key, 'not_equals', Value}
The "key
" attribute is not exactly equal to Value
. This is also used to attain a query like foo IS NOT NULL
: {foo, 'not_equals', undefined}
.
key ∈ [Value1, Value2, ...]
{key, 'in', [Value1, Value2, ...]}
The "key
" attribute is equal to at least one element on the right-hand side.
key ∉ [Value1, Value2, ...]
{key, 'not_in', [Value1, Value2, ...]}
The "key
" attribute is not equal to any element on the right-hand side.
key ∈ {Min, Max}
{key, 'in', {Min, Max}}
The "key
" attribute is numerically between Min
and Max
.
key ∉ {Min, Max}
{key, 'not_in', {Min, Max}}
The "key
" attribute is not between Min
and Max
.
key ∼ RegularExpression
{key, 'matches', RegularExpression}
The "key
" attribute matches the RegularExpression
. To perform a case-insensitive match, the expression should start with an asterisk (e.g. *erlang
).
key ≁ RegularExpression
{key, 'not_matches', RegularExpression}
The "key" attribute does not match the RegularExpression.
.
key ∋ Token
{key, 'contains', Token}
The "key" attribute contains Token
.
key ∌ Token
{key, 'not_contains', Token}
The "key
" attribute does not contain Token
.
key ⊇ [Token1, Token2, ...]
{key, 'contains_all', [Token1, Token2, ...]}
The "key
" attribute contains all tokens on the right-hand side.
key ⊉ [Token1, Token2, ...]
{key, 'not_contains_all', [Token1, Token2, ...]}
The "key
" attribute does not contain all tokens on the right-hand side.
key ∩ [Token1, Token2, ...]
{key, 'contains_any', [Token1, Token2, ...]}
The "key
" attribute contains at least one of the tokens on the right-hand side.
key ⊥ [Token1, Token2, ...]
{key, 'contains_none', [Token1, Token2, ...]}
The "key
" attribute contains none of the tokens on the right-hand side.
key > Value
{key, 'gt', Value}
The "key
" attribute is greater than Value
.
key < Value
{key, 'lt', Value}
The "key" attribute is less than Value
.
key ≥ Value
{key, 'ge', Value}
The "key" attribute is greater than or equal to Value
.
key ≤ Value
{key, 'le', Value}
The "key" attribute is less than or equal to Value
.