Basic SQL query builder.
The following example uses the query builder to extend an SQL query
with WHERE, ORDER BY, and LIMIT parameters. An observation database
observ.sqlite
must be provided, from which an observation id
observ_id
is read.
character(len=:), allocatable :: node_id, observ_id, sensor_id, target_id
character(len=:), allocatable :: sql
integer :: rc
type(db_type) :: db
type(db_query_type) :: dbq
type(db_stmt_type) :: dbs
! Query parameters.
node_id = 'dummy-node'
sensor_id = 'dummy-sensor'
target_id = 'dummy-target'
! Open an existing observation database first.
rc = dm_db_open(db, 'observ.sqlite', read_only=.true.)
call dm_error_out(rc, fatal=.true.)
! Set SQL base query string.
call dm_db_query_set_sql(dbq, &
'SELECT observs.id FROM observs ' // &
'INNER JOIN nodes ON nodes.row_id = observs.node_id ' // &
'INNER JOIN sensors ON sensors.row_id = observs.sensor_id ' // &
'INNER JOIN targets ON targets.row_id = observs.target_id')
! Set WHERE clause of the query.
call dm_db_query_where(dbq, 'nodes.id = ?', node_id)
call dm_db_query_where(dbq, 'sensors.id = ?', sensor_id)
call dm_db_query_where(dbq, 'targets.id = ?', target_id)
! Set ORDER BY and LIMIT of the query.
call dm_db_query_set_order(dbq, by='observs.timestamp', desc=.true.)
call dm_db_query_set_limit(dbq, 1_i8)
! Create full query string from base query.
sql = dm_db_query_build(dbq)
sql_block: block
! Prepare the database statement.
rc = dm_db_prepare(db, dbs, sql)
if (dm_is_error(rc)) exit sql_block
! Bind the query parameters to the statement.
rc = dm_db_bind(dbs, dbq)
if (dm_is_error(rc)) exit sql_block
! Run the statement.
rc = dm_db_step(dbs)
if (rc /= E_DB_ROW) exit sql_block
! Get next row as allocatable character string.
rc = dm_db_row_next(dbs, observ_id)
if (dm_is_error(rc)) exit sql_block
end block sql_block
call dm_error_out(rc, verbose=.true.)
call dm_db_query_destroy(dbq)
call dm_db_finalize(dbs)
call dm_db_close(db)
if (allocated(observ_id)) print '("observ_id: ", a)', observ_id
Make sure to not add more than DB_QUERY_NPARAMS
parameters to a query
or increase the constant first (32 is assumed to be sufficient for WHERE
and SET parameters).
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
integer, | public, | parameter | :: | DB_QUERY_TYPE_NONE | = | 0 |
No type (invalid). |
integer, | public, | parameter | :: | DB_QUERY_TYPE_DOUBLE | = | 1 |
SQLite double precision. |
integer, | public, | parameter | :: | DB_QUERY_TYPE_INT | = | 2 |
SQLite 32-bit integer. |
integer, | public, | parameter | :: | DB_QUERY_TYPE_INT64 | = | 3 |
SQLite 64-bit integer. |
integer, | public, | parameter | :: | DB_QUERY_TYPE_TEXT | = | 4 |
SQLite text. |
Generic subroutine to add SET values to UPDATE query. The procedures do not validate that values have been added only once. The function is prone to SQL injections. Only pass parametrised strings!
Adds double precision SET parameter to query. Returns E_LIMIT
in
error
if parameter limit has been reached.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in) | :: | column |
Column name. |
||
real(kind=r8), | intent(in) | :: | value |
New column value. |
||
integer, | intent(out), | optional | :: | error |
Error code. |
Adds 32-bit integer SET parameter to query. Returns E_LIMIT
if
parameter limit has been reached.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in) | :: | column |
Column name. |
||
integer(kind=i4), | intent(in) | :: | value |
New column value. |
||
integer, | intent(out), | optional | :: | error |
Error code. |
Adds 64-bit integer SET parameter to query. Returns E_LIMIT
if
parameter limit has been reached.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in) | :: | column |
Column name. |
||
integer(kind=i8), | intent(in) | :: | value |
New column value. |
||
integer, | intent(out), | optional | :: | error |
Error code. |
Adds text parameter to SET query. Returns E_LIMIT
if parameter
limit has been reached.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in) | :: | column |
Column name. |
||
character(len=*), | intent(in) | :: | value |
New column value. |
||
integer, | intent(out), | optional | :: | error |
Error code. |
Generic subroutine to add WHERE values to query. The procedures do not validate that values have been added only once. The function is prone to SQL injections. Only pass parametrised strings!
Adds double precision WHERE parameter to query. Returns E_LIMIT
in
error
if parameter limit has been reached.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in) | :: | param |
Query parameter. |
||
real(kind=r8), | intent(in) | :: | value |
Query parameter value. |
||
integer, | intent(out), | optional | :: | error |
Error code. |
Adds 32-bit integer WHERE parameter to query. Returns E_LIMIT
if
parameter limit has been reached.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in) | :: | param |
Query parameter. |
||
integer(kind=i4), | intent(in) | :: | value |
Query parameter value. |
||
integer, | intent(out), | optional | :: | error |
Error code. |
Adds 64-bit integer WHERE parameter to query. Returns E_LIMIT
if
parameter limit has been reached.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in) | :: | param |
Query parameter. |
||
integer(kind=i8), | intent(in) | :: | value |
Query parameter value. |
||
integer, | intent(out), | optional | :: | error |
Error code. |
Adds text parameter to WHERE query. Returns E_LIMIT
if parameter
limit has been reached. Empty strings and strings containing only
white-space characters are ignored, unless argument empty
is set
to .true.
.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in) | :: | param |
Query parameter. |
||
character(len=*), | intent(in) | :: | value |
Query parameter value. |
||
logical, | intent(in), | optional | :: | empty |
Add empty string. |
|
integer, | intent(out), | optional | :: | error |
Error code. |
Single WHERE or SET parameter of database query.
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
integer, | public | :: | type | = | DB_QUERY_TYPE_NONE |
Value type. |
|
real(kind=r8), | public | :: | value_double | = | 0.0_r8 |
Double value. |
|
integer, | public | :: | value_int | = | 0 |
Integer value. |
|
integer(kind=i8), | public | :: | value_int64 | = | 0.0_i8 |
64-bit integer value. |
|
character(len=:), | public, | allocatable | :: | value_text |
Text value. |
||
character(len=:), | public, | allocatable | :: | sql |
WHERE clause or column name. |
Database query with SET values (for SQL UPDATE), WHERE parameters, LIMIT, and ORDER BY. Do not modify this derived type directly!
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
character(len=:), | public, | allocatable | :: | sql |
SQL base query. |
||
character(len=:), | public, | allocatable | :: | order_by |
ORDER BY clause. |
||
logical, | public | :: | order_desc | = | .false. |
ASC or DESC order. |
|
integer(kind=i8), | public | :: | limit | = | 0_i8 |
Row limit. |
|
integer, | public | :: | nparams | = | 0 |
Current WHERE parameter array size. |
|
integer, | public | :: | nupdates | = | 0 |
Current SET parameter array size. |
|
type(db_query_param_type), | public | :: | params(DB_QUERY_NPARAMS) |
WHERE parameter array. |
|||
type(db_query_param_type), | public | :: | updates(DB_QUERY_NPARAMS) |
SET parameter array. |
Returns SQL string from query. If no base SQL query base
is
passed, uses query attribute sql
instead. If attribute sql
is
not allocated, the SQL base query will be empty (and only the WHERE,
ORDER BY, and LIMIT parameters are returned). A passed base query
will overwrite the attribute of argument db_query
.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in), | optional | :: | base |
Base query string. |
SQL string.
Resets query.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
Sets LIMIT
clause of query. If argument limit
is not passed, not
limit is set. Passing 0 disables the LIMIT parameter.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
integer(kind=i8), | intent(in), | optional | :: | limit |
Limit value. |
Sets ORDER BY
clause of query. Argument by
must be a valid field
name. The function is prone to SQL injections. Only pass
parametrised strings! If desc
is not passed, ascending order is
used.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in) | :: | by |
Field name. |
||
logical, | intent(in), | optional | :: | desc |
Descending order. |
Sets SQL base query. The function is prone to SQL injections. Only pass parametrised strings!
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(db_query_type), | intent(inout) | :: | db_query |
Database query type. |
||
character(len=*), | intent(in) | :: | base |
SQL base query. |