icql-dba
Version:
An SQLite DB Adapter built with BetterSQLite3
160 lines (142 loc) • 6.17 kB
text/coffeescript
'use strict'
############################################################################################################
CND = require 'cnd'
rpr = CND.rpr
badge = 'ICQL-DBA/FUNCTIONS-MIXIN'
debug = CND.get_logger 'debug', badge
warn = CND.get_logger 'warn', badge
info = CND.get_logger 'info', badge
urge = CND.get_logger 'urge', badge
help = CND.get_logger 'help', badge
whisper = CND.get_logger 'whisper', badge
echo = CND.echo.bind CND
#...........................................................................................................
PATH = require 'path'
FS = require 'fs'
E = require './errors'
{ misfit } = require './common'
SQL = String.raw
{ lets
freeze } = require 'letsfreezethat'
#-----------------------------------------------------------------------------------------------------------
= ( clasz = Object ) => class extends clasz
#---------------------------------------------------------------------------------------------------------
_register_udf: ( udf_type, cfg ) ->
### TAINT validate more thoroughly, especially cfg._dba_udf_type ###
### TAINT consider to use (virtual?) table for this ###
.validate.nonempty_text udf_type
.validate.object cfg
.validate.nonempty_text cfg.name
{ name, } = cfg
switch udf_type
when 'single_valued'
entry =
name: name
arity: cfg.call.length ### TAINT respect varargs ###
else
entry =
name: name
cfg: cfg
= lets , ( d ) -> d[ cfg.name ] = entry
return null
#=========================================================================================================
# USER-DEFINED FUNCTIONS
#---------------------------------------------------------------------------------------------------------
create_function: ( cfg ) ->
.validate.dba_create_function_cfg ( cfg = { .defaults.dba_create_function_cfg..., cfg..., } )
{ name
call
directOnly
deterministic
varargs } = cfg
.function name, { deterministic, varargs, directOnly, }, call
'single_valued', cfg
return null
#---------------------------------------------------------------------------------------------------------
create_aggregate_function: ( cfg ) ->
.validate.dba_create_aggregate_function_cfg ( cfg = { .defaults.dba_create_aggregate_function_cfg..., cfg..., } )
{ name
start
step
directOnly
deterministic
varargs } = cfg
.aggregate name, { start, step, deterministic, varargs, directOnly, }
'aggregate', cfg
return null
#---------------------------------------------------------------------------------------------------------
create_window_function: ( cfg ) ->
.validate.dba_create_window_function_cfg ( cfg = { .defaults.dba_create_window_function_cfg..., cfg..., } )
{ name
start
step
inverse
result
directOnly
deterministic
varargs } = cfg
.aggregate name, { start, step, inverse, result, deterministic, varargs, directOnly, }
'window', cfg
return null
#---------------------------------------------------------------------------------------------------------
create_table_function: ( cfg ) ->
.validate.dba_create_table_function_cfg ( cfg = { .defaults.dba_create_table_function_cfg..., cfg..., } )
{ name
parameters
columns
rows
directOnly
deterministic
varargs } = cfg
.table name, { parameters, columns, rows, deterministic, varargs, directOnly, }
'table_function', cfg
return null
#---------------------------------------------------------------------------------------------------------
create_virtual_table: ( cfg ) ->
.validate.dba_create_virtual_table_cfg ( cfg = { .defaults.dba_create_virtual_table_cfg..., cfg..., } )
{ name, create, } = cfg
.table name, create
'virtual_table', cfg
return null
#=========================================================================================================
# CONTEXT HANDLERS
#---------------------------------------------------------------------------------------------------------
with_transaction: ( cfg, f ) ->
switch arity = arguments.length
when 1 then [ cfg, f, ] = [ null, cfg, ]
when 2 then null
else throw new E.Dba_wrong_arity '^dba-functions@901^', 'with_transaction()', 1, 2, arity
.validate.dba_with_transaction_cfg ( cfg = { .defaults.dba_with_transaction_cfg..., cfg..., } )
.validate.function f
throw new E.Dba_no_nested_transactions '^dba-functions@901^' if .inTransaction
SQL"begin #{cfg.mode} transaction;"
error = null
try
R = f()
catch error
SQL"rollback;"
throw error
try
SQL"commit;"
catch error
SQL"rollback;"
return null
#---------------------------------------------------------------------------------------------------------
with_unsafe_mode: ( f ) ->
.validate.function f
unsafe_mode_state =
true
try
R = f()
finally
unsafe_mode_state
return R
#---------------------------------------------------------------------------------------------------------
with_foreign_keys_deferred: ( f ) ->
.validate.function f
R = null
throw new E.Dba_no_deferred_fks_in_tx '^dba-functions@901^' if .inTransaction
=>
.pragma SQL"defer_foreign_keys=true"
R = f()
return R