-- Autogenerated with DRAKON Editor 1.32
local table = table
local string = string
local pairs = pairs
local ipairs = ipairs
local type = type
local box = box
local tostring = tostring
local tonumber = tonumber
local print = print
local math = math
local os = os
local pcall = pcall
local error = error
local select = select
local unpack = unpack
local digest = require("digest")

local global_cfg = global_cfg
local globs = globs

local clock = require("clock")
local log = require("log")
local digest = require("digest")
local fiber = require("fiber")
local utils = require("utils")
local fun = require("fun")
local json = require("json")

local utf8 = require("lua-utf8")

local mysql = require("mysql")

local folders = box.space.folders
local items = box.space.items
local spaces = box.space.spaces
local usettings = box.space.usettings
local recent = box.space.recent

local users = box.space.users
local sessions = box.space.sessions
local creds = box.space.creds
local usecrets = box.space.usecrets

local payments = box.space.payments
local agreements = box.space.agreements
local scheduled = box.space.scheduled
local transactions = box.space.transactions
local licenses = box.space.licenses
local coupons = box.space.coupons

local search_yield = 0.02
local current_version = 20180619

local module = {}
module.connections = {}

module.verbose = false

local batch_size = 20

setfenv(1, {}) 

function add_auto_table(name, primary_key, output)
    -- item 1611
    add_table(
    	name,
    	{
    		{primary_key, "auto"},
    		{"data", "json"}
    	},
    	{primary_key},
    	nil,
    	output
    )
end

function add_simple_table(name, primary_key, output)
    -- item 1605
    add_table(
    	name,
    	{
    		{primary_key, "str"},
    		{"data", "json"}
    	},
    	{primary_key},
    	nil,
    	output
    )
end

function add_table(name, fields, pk, index, output)
    local flist, item
    -- item 1478
    flist = utils.map(
        fields,
        create_field
    )
    -- item 1471
    item = {
        name = name,
        fields = flist,
        pk = pk,
        indexes = {}
    }
    -- item 1473
    if index then
        -- item 1476
        table.insert(
            item.indexes,
            index
        )
    end
    -- item 1472
    table.insert(
        output,
        item
    )
    -- item 1477
    return item
end

function agreement_delete(id)
    -- item 1645
    delete_row(
        "agreements",
        id
    )
end

function agreement_get(id)
    local row
    -- item 590
    row = get_row_by_pk(
        "agreements",
        id
    )
    -- item 593
    if row then
        -- item 592
        return row[3], row[2]
    else
        -- item 596
        return nil
    end
end

function agreement_get_by_order_ref(order_ref)
    local found
    -- item 1688
    found = get_rows_by_column(
        "agreements",
        "order_ref",
        order_ref
    )
    -- item 610
    return found
end

function agreement_insert(id, order_ref, data)
    -- item 1741
    insert_row(
        "agreements",
        id,
        order_ref,
        data
    )
end

function agreement_update(agreement_id, order_ref, data)
    -- item 622
    replace_row(
        "agreements",
        agreement_id,
        order_ref,
        data
    )
end

function agreement_update_data(agreement_id, agreement)
    -- item 1854
    update_one(
        "agreements",
        "data",
        agreement,
        agreement_id
    )
end

function agreement_update_order(agreement_id, order_ref)
    -- item 629
    update_one(
        "agreements",
        "order_ref",
        order_ref,
        agreement_id
    )
end

function begin()
    local connector
    -- item 1165
    connector = get_connector()
    -- item 2033
    connector:begin()
end

function build_full_field_list(table_info)
    local get_name, names
    -- item 2597
    get_name = function(field) 
        return field.name
    end
    -- item 2592
    names = utils.map(
        table_info.fields,
        get_name
    )
    -- item 2596
    return utils.join(
        names,
        ", "
    )
end

function build_full_insert_sql(table_info)
    local names_str, questions, sql
    -- item 2366
    names_str = build_full_field_list(
        table_info
    )
    -- item 2367
    questions = repeat_questions(
        #table_info.fields
    )
    -- item 2365
    sql = "insert into " ..
     table_info.name .. 
     " (" ..
     names_str ..
     ") values (" ..
     questions ..
     ")"
    -- item 2368
    return sql
end

function build_full_insert_sql_many(table_info, count)
    local all_values, names_str, questions, values_str
    -- item 2599
    names_str = build_full_field_list(
        table_info
    )
    -- item 2600
    questions = repeat_questions(
        #table_info.fields
    )
    -- item 2603
    values_str = "(" ..
      questions ..
      ")"
    -- item 2604
    all_values = repeat_with_comma(
        values_str,
        count
    )
    -- item 2598
    return "insert into " ..
     table_info.name .. 
     " (" ..
     names_str ..
     ") values " ..
     all_values
end

function build_insert_sql(table_info, ...)
    local actual_length, field_count, message, names, names_str, questions, sql
    -- item 1707
    field_count = 0
    names = {}
    actual_length = select("#", ...)
    for _, field in ipairs(table_info.fields) do
        -- item 1710
        if field.type == "auto" then
            
        else
            -- item 1714
            table.insert(
                names,
                field.name
            )
            -- item 1713
            field_count = field_count + 1
        end
    end
    -- item 1725
    if actual_length == field_count then
        -- item 1731
        names_str = utils.join(
            names,
            ", "
        )
        -- item 1732
        questions = repeat_questions(
            field_count
        )
        -- item 1730
        sql = "insert into " ..
         table_info.name .. 
         " (" ..
         names_str ..
         ") values (" ..
         questions ..
         ")"
        -- item 1898
        return sql
    else
        -- item 1728
        message = operation ..
         "INSERT into table " ..
         table_info.name ..
         " requires " ..
         tostring(field_count) ..
         " values"
        -- item 1729
        error(message)
    end
end

function build_pk_where(operation, table_info, ...)
    local actual_length, key_length, message
    -- item 1629
    key_length = #table_info.pk
    actual_length = select("#", ...)
    -- item 1630
    if actual_length == key_length then
        -- item 1881
        return build_pk_where_dumb(
            table_info
        )
    else
        -- item 1633
        message = operation ..
         ": The primary key of table " ..
         table_info.name ..
         " consists of " ..
         tostring(key_length) ..
         " columns, got " ..
         tostring(actual_length) ..
         " key values"
        -- item 1634
        error(message)
    end
end

function build_pk_where_dumb(table_info)
    local condition, conditions
    -- item 1877
    conditions = {}
    for _, column in ipairs(table_info.pk) do
        -- item 1878
        table.insert(
            conditions,
            column .. " = ?"
        )
    end
    -- item 1879
    condition = utils.join(
        conditions,
        " and "
    )
    -- item 1880
    return " where " .. condition
end

function build_replace_sql(table_info, ...)
    local actual_length, args, field_count, i, message, names, names_str, pk, questions, set, update, update_str
    -- item 1847
    args = {...}
    -- item 1757
    actual_length = select("#", ...)
    field_count = #table_info.fields
    -- item 1765
    if actual_length == field_count then
        -- item 1846
        pk = utils.list_to_set(
            table_info.pk
        )
        -- item 1790
        names = {}
        update = {}
        -- item 1849
        i = 1
        for _, field in ipairs(table_info.fields) do
            -- item 1764
            table.insert(
                names,
                field.name
            )
            -- item 1850
            if pk[field.name] then
                
            else
                -- item 1773
                set = field.name ..
                 " = ?"
                -- item 1775
                table.insert(
                    update,
                    set
                )
                -- item 1853
                table.insert(
                    args,
                    args[i]
                )
            end
            -- item 1848
            i = i + 1
        end
        -- item 1774
        update_str = utils.join(
            update,
            ", "
        )
        -- item 1771
        names_str = utils.join(
            names,
            ", "
        )
        -- item 1772
        questions = repeat_questions(
            field_count
        )
        -- item 1770
        return "insert into " ..
         table_info.name .. 
         " (" ..
         names_str ..
         ") values (" ..
         questions ..
         ") on duplicate key update " ..
         update_str, args
    else
        -- item 1768
        message = operation ..
         "INSERT into table " ..
         table_info.name ..
         " requires " ..
         tostring(field_count) ..
         " values"
        -- item 1769
        error(message)
    end
end

function build_schema()
    local tables
    -- item 1508
    tables = make_schema()
    -- item 1511
    module.tables = {}
    module.table_list = {}
    for _, item in ipairs(tables) do
        -- item 1512
        module.tables[item.name] = item
        -- item 1513
        table.insert(
            module.table_list,
            item.name
        )
    end
end

function clean_up()
    local connector
    -- item 2039
    connector = get_connector()
    -- item 2034
    connector:clean_up()
end

function commit()
    local connector
    -- item 2035
    connector = get_connector()
    -- item 2036
    connector:commit()
end

function connect(self)
    -- item 2031
    self.conn = get_conn_from_pool()
end

function connector_machine_Connected_begin(self, msg)
    -- item 2002
    self.conn:begin()
    -- item 2000
    self.state = "Transaction"
end

function connector_machine_Connected_clean_up(self, msg)
    -- item 2022
    disconnect(self)
    -- item 1964
    self.state = "Idle"
end

function connector_machine_Connected_commit(self, msg)
    -- item 2477
    error("Not in transaction")
    -- item 2476
    self.state = "Connected"
end

function connector_machine_Connected_connect(self, msg)
    -- item 1955
    self.state = "Connected"
    return self.conn
end

function connector_machine_Connected_disconnect(self, msg)
    -- item 2022
    disconnect(self)
    -- item 1964
    self.state = "Idle"
end

function connector_machine_Connected_rollback(self, msg)
    -- item 2477
    error("Not in transaction")
    -- item 2476
    self.state = "Connected"
end

function connector_machine_Idle_begin(self, msg)
    -- item 2032
    connect(self)
    -- item 1991
    self.conn:begin()
    -- item 1954
    self.state = "Transaction"
end

function connector_machine_Idle_commit(self, msg)
    -- item 2470
    error("Not in transaction")
    -- item 2469
    self.state = "Idle"
end

function connector_machine_Idle_connect(self, msg)
    -- item 1989
    connect(self)
    -- item 1925
    self.state = "Connected"
    return self.conn
end

function connector_machine_Idle_rollback(self, msg)
    -- item 2470
    error("Not in transaction")
    -- item 2469
    self.state = "Idle"
end

function connector_machine_Transaction_begin(self, msg)
    -- item 2481
    error("Already in transaction")
    -- item 2480
    self.state = "Transaction"
end

function connector_machine_Transaction_clean_up(self, msg)
    -- item 2014
    self.conn:rollback()
    -- item 2024
    disconnect(self)
    -- item 2008
    self.state = "Idle"
end

function connector_machine_Transaction_commit(self, msg)
    -- item 2013
    self.conn:commit()
    -- item 2023
    disconnect(self)
    -- item 2011
    self.state = "Idle"
end

function connector_machine_Transaction_connect(self, msg)
    -- item 1945
    self.state = "Transaction"
    return self.conn
end

function connector_machine_Transaction_disconnect(self, msg)
    -- item 2045
    self.state = "Transaction"
end

function connector_machine_Transaction_rollback(self, msg)
    -- item 2014
    self.conn:rollback()
    -- item 2024
    disconnect(self)
    -- item 2008
    self.state = "Idle"
end

function convert_to_array(table_info, row)
    local output, value
    -- item 2074
    output = {}
    for _, column in ipairs(table_info.fields) do
        -- item 2078
        value = row[column.name]
        -- item 2231
        if (column.type == "json") and (value) then
            -- item 2290
            value = json.decode(value)
        end
        -- item 2077
        table.insert(
            output,
            value
        )
    end
    -- item 2079
    return output
end

function coupon_get(code)
    local data, row
    -- item 1885
    row = get_row_by_pk(
        "coupons",
        code
    )
    -- item 757
    if row then
        -- item 762
        data = row[2]
        -- item 761
        return data
    else
        -- item 760
        return nil
    end
end

function coupon_insert(code, data)
    -- item 1886
    insert_row(
        "coupons",
        code,
        data
    )
end

function coupon_update(code, data)
    -- item 1887
    replace_row(
        "coupons",
        code,
        data
    )
end

function create_database()
    local connection, create, info
    -- item 1501
    module.db = global_cfg.mysql.db
    -- item 1502
    info = {
        host = global_cfg.mysql.host,
        user = global_cfg.mysql.user,
        password = global_cfg.mysql.password
    }
    -- item 1504
    connection = mysql.connect(
        info
    )
    -- item 1503
    log.info(
        "Connected to MySQL instance at " .. info.host
    )
    -- item 1499
    create = "CREATE DATABASE IF NOT EXISTS " .. 
    	module.db .. 
    	" CHARACTER SET utf8 COLLATE utf8_general_ci"
    -- item 1500
    connection:execute(create)
end

function create_field(item)
    -- item 1490
    return {
        name = item[1],
        type = item[2]
    }
end

function create_index(name, columns, unique)
    -- item 1484
    return {
        name = name,
        columns = columns,
        unique = unique
    }
end

function create_pool()
    -- item 1494
    module.pool = mysql.pool_create(
        global_cfg.mysql
    )
    -- item 1495
    log.info(
        "Connected to MySQL instance at " .. global_cfg.mysql.host
    )
end

function create_table(info)
    local body, body_str, make_column, new_index, pk, pk_constraint, sql
    -- item 1528
    pk = utils.list_to_set(
        info.pk
    )
    -- item 1529
    make_column = function(field) 
        return make_column_line(field, pk)
    end
    -- item 1530
    body = utils.map(
        info.fields,
        make_column
    )
    -- item 1531
    pk_constraint = make_pk_line(info)
    -- item 1532
    table.insert(
        body,
        pk_constraint
    )
    -- item 1533
    body_str = utils.join(
        body,
        ",\n    "
    )
    -- item 1534
    sql = "create table if not exists " ..
      info.name ..
      " (\n    " ..
      body_str ..
      "\n)"
    -- item 1535
    exec(sql)
    -- item 1540
    new_index = function(index) 
        return make_index(info, index)
    end
    -- item 1541
    utils.map(
        info.indexes,
        new_index
    )
    -- item 1536
    log.info(
      "Table " .. info.name .. " OK"
    )
end

function cred_delete(user_id)
    -- item 2163
    delete_row(
        "creds",
        user_id
    )
end

function cred_get(user_id)
    local hash, raw, row, salt
    -- item 2164
    row = get_row_by_pk(
        "creds",
        user_id
    )
    -- item 506
    if row then
        -- item 510
        raw = row[2]
        -- item 2293
        hash = digest.base64_decode(raw.hash) 
        salt = digest.base64_decode(raw.salt)
        -- item 2292
        return {
            hash = hash,
            salt = salt,
            valid_from = raw.valid_from
        }
    else
        -- item 509
        return nil
    end
end

function cred_upsert(user_id, cred)
    local value
    -- item 2289
    value = encode_cred(cred)
    -- item 2165
    replace_row(
        "creds",
        user_id,
        value
    )
end

function delete_row(table_name, ...)
    local sql, table_info, where
    -- item 1618
    table_info = get_table(
        table_name
    )
    -- item 1619
    where = build_pk_where(
    	"delete_row",
    	table_info,
    	...
    )
    -- item 1643
    sql = "delete from " ..
      table_name ..
      where
    -- item 1644
    exec(sql, ...)
end

function disconnect(self)
    -- item 2020
    module.pool:put(
        self.conn
    )
    -- item 2021
    self.conn = nil
end

function element_to_line(element, lines)
    local line
    -- item 2729
    line = print_element(element)
    -- item 2755
    table.insert(
        lines,
        line
    )
end

function element_to_lines(element, depth, lines)
    local end_tag, indent, line, line2, start_tag
    -- item 2743
    indent = make_indent(depth)
    -- item 2751
    if #element.children == 0 then
        -- item 2766
        line = print_element(element)
        -- item 2767
        line2 = indent .. line
        -- item 2757
        table.insert(
            lines,
            line2
        )
    else
        -- item 2741
        start_tag =  indent .. "<" .. 
          element.tag .. ">"
        -- item 2769
        table.insert(
            lines,
            start_tag
        )
        for _, child in ipairs(element.children) do
            -- item 2773
            element_to_lines(
                child,
                depth + 1,
                lines
            )
        end
        -- item 2768
        end_tag =  indent .. "</" .. 
          element.tag .. ">"
        -- item 2770
        table.insert(
            lines,
            end_tag
        )
    end
end

function encode_cred(cred)
    local hash, salt
    -- item 2417
    hash = digest.base64_encode(cred.hash) 
    salt = digest.base64_encode(cred.salt)
    -- item 2418
    return {
        hash = hash,
        salt = salt,
        valid_from = cred.valid_from
    }
end

function exec(command, ...)
    local args
    -- item 2212
    args = {...}
    -- item 2213
    return exec_arr(command, args)
end

function exec_arr(command, args_raw)
    local connection, connector, tuples
    -- item 2046
    connector = get_connector()
    connection = connector:connect()
    -- item 2342
    tuples = exec_arr_kernel(
        connection,
        command,
        args_raw
    )
    -- item 2047
    connector:disconnect()
    -- item 1812
    return tuples
end

function exec_arr_kernel(connection, command, args_raw)
    local args, full_command, status, tuples
    -- item 2338
    args = serialize_params(args_raw)
    -- item 2299
    full_command = command .. ";"
    -- item 2302
    if module.verbose then
        -- item 2301
        print_params(args)
        log.info(full_command)
    end
    -- item 2341
    tuples, status = connection:execute(
        full_command,
        unpack(args)
    )
    -- item 2305
    if module.verbose then
        -- item 2337
        print_rows(tuples)
        -- item 2300
        log.info("status: " .. tostring(status))
    end
    -- item 2308
    return tuples
end

function folder_delete(space_id, folder_id)
    -- item 2120
    delete_row(
        "folders",
        space_id,
        folder_id
    )
end

function folder_get(space_id, folder_id)
    local row
    -- item 2121
    row = get_row_by_pk(
        "folders",
        space_id,
        folder_id
    )
    -- item 270
    if row then
        -- item 269
        local fdata = row[3]
        -- item 268
        return fdata
    else
        -- item 273
        return nil
    end
end

function folder_get_all()
    -- item 2122
    return get_all_rows(
        "folders"
    )
end

function folder_get_by_space(space_id)
    -- item 2123
    return get_rows_by_column(
        "folders",
        "space_id",
        space_id
    )
end

function folder_insert(space_id, folder_id, fdata)
    -- item 2124
    insert_row(
        "folders",
        space_id,
        folder_id,
        fdata
    )
end

function folder_tree_delete(space_id, folder_id)
    -- item 2637
    delete_row(
        "folder_tree",
        space_id,
        folder_id
    )
end

function folder_tree_get(space_id, folder_id)
    local row
    -- item 2650
    row = get_row_by_pk(
        "folder_tree",
        space_id,
        folder_id
    )
    -- item 2652
    if row then
        -- item 2651
        return row[3]
    else
        -- item 2655
        return nil
    end
end

function folder_tree_get_by_parent(space_id, parent_id)
    -- item 2643
    return get_rows_by_column2(
        "folder_tree",
        "space_id",
        space_id,
        "parent_id",
        parent_id
    )
end

function folder_tree_upsert(space_id, folder_id, parent_id)
    -- item 2631
    replace_row(
        "folder_tree",
        space_id,
        folder_id,
        parent_id,
        {}
    )
end

function folder_update(space_id, folder_id, fdata)
    -- item 2125
    replace_row(
        "folders",
        space_id,
        folder_id,
        fdata
    )
end

function from_tara_to_mysql()
    local info
    for _, name in ipairs(module.table_list) do
        -- item 2375
        info = module.tables[name]
        -- item 2374
        import_table_data(info)
    end
end

function get_all_rows(table_name)
    local convert, result, rows, sql, table_info
    -- item 2098
    table_info = get_table(
        table_name
    )
    -- item 2100
    sql = "select * from " ..
      table_name
    -- item 2101
    result = exec(sql)
    -- item 2103
    rows = result[1]
    -- item 2104
    convert = function(row) 
        return convert_to_array(table_info, row)
    end
    -- item 2102
    return utils.map(
        rows,
        convert
    )
end

function get_conn_from_pool()
    local connection, get_conn
    -- item 1970
    get_conn = function() 
        return module.pool:get()
    end
    while true do
        -- item 1984
        connection = hide_exception(get_conn)
        -- item 1983
        if connection then
            break
        end
        -- item 1988
        fiber.sleep(0.1)
    end
    -- item 1985
    return connection
end

function get_connector()
    local connector, fiber_id
    -- item 1130
    fiber_id = get_fiber_id()
    -- item 1135
    connector = module.connections[fiber_id]
    -- item 1131
    if connector then
        
    else
        -- item 1134
        connector = connector_machine()
        module.connections[fiber_id] = connector
    end
    -- item 1136
    return connector
end

function get_count(table_name)
    local result, rows, sql
    -- item 2132
    sql = "select count(*) count from " ..
      table_name
    -- item 2133
    result = exec(sql)
    -- item 2135
    rows = result[1]
    -- item 2136
    return rows[1].count
end

function get_fiber_id()
    -- item 1093
    return fiber.self():id()
end

function get_one_row(table_info, result)
    local row, rows
    -- item 1665
    rows = result[1]
    -- item 1666
    if #rows == 0 then
        -- item 1669
        return nil
    else
        -- item 1670
        row = rows[1]
        -- item 2080
        return convert_to_array(
            table_info,
            row
        )
    end
end

function get_row_by_column(table_name, column, value)
    local result, sql, table_info, where
    -- item 1683
    table_info = get_table(
        table_name
    )
    -- item 1684
    where = " where " ..
     column ..
     " = ?"
    -- item 1685
    sql = "select * from " ..
      table_name ..
      where
    -- item 1686
    result = exec(sql, value)
    -- item 1687
    return get_one_row(
        table_info,
        result
    )
end

function get_row_by_pk(table_name, ...)
    local result, sql, table_info, where
    -- item 1652
    table_info = get_table(
        table_name
    )
    -- item 1653
    where = build_pk_where(
    	"get_row_by_pk",
    	table_info,
    	...
    )
    -- item 1654
    sql = "select * from " ..
      table_name ..
      where
    -- item 1655
    result = exec(sql, ...)
    -- item 1677
    return get_one_row(
        table_info,
        result
    )
end

function get_rows_by_column(table_name, column, value)
    local convert, result, rows, sql, table_info, where
    -- item 2086
    table_info = get_table(
        table_name
    )
    -- item 2087
    where = " where " ..
     column ..
     " = ?"
    -- item 2088
    sql = "select * from " ..
      table_name ..
      where
    -- item 2089
    result = exec_arr(sql, {value})
    -- item 2091
    rows = result[1]
    -- item 2092
    convert = function(row) 
        return convert_to_array(table_info, row)
    end
    -- item 2090
    return utils.map(
        rows,
        convert
    )
end

function get_rows_by_column2(table_name, column, value, column2, value2)
    local convert, result, rows, sql, table_info, where
    -- item 2145
    table_info = get_table(
        table_name
    )
    -- item 2146
    where = " where " ..
      column ..
      " = ? and " ..
      column2 ..
      " = ?"
    -- item 2147
    sql = "select * from " ..
      table_name ..
      where
    -- item 2148
    result = exec_arr(sql, {value, value2})
    -- item 2150
    rows = result[1]
    -- item 2151
    convert = function(row) 
        return convert_to_array(table_info, row)
    end
    -- item 2149
    return utils.map(
        rows,
        convert
    )
end

function get_table(table_name)
    local table_info
    -- item 1612
    table_info = module.tables[table_name]
    -- item 1613
    if table_info then
        -- item 1617
        return table_info
    else
        -- item 1616
        error(
            "Table does not exist: " .. table_name
        )
    end
end

function h2(text, lines)
    local element
    -- item 2706
    element = make(nil, "h2", text)
    -- item 2707
    element_to_line(element, lines)
end

function h3(text, lines)
    local element
    -- item 2714
    element = make(nil, "h3", text)
    -- item 2756
    element_to_line(element, lines)
end

function has_auto(table_info)
    for _, field in ipairs(table_info.fields) do
        -- item 1697
        if field.type == "auto" then
            -- item 1700
            return true
        end
    end
    -- item 1701
    return false
end

function hide_exception(action)
    -- item 1976
    local ok, result = pcall(action)
    -- item 1977
    if ok then
        -- item 1981
        return result
    else
        -- item 1982
        return nil
    end
end

function import_table_data(table_info)
    local count, cred, inserter, rows, space, sql, truncate, user_id, value
    -- item 2390
    space = box.space[table_info.name]
    -- item 2391
    rows = space:select()
    -- item 2622
    log.info("Table " ..
      table_info.name ..
      "  " .. #rows)
    -- item 2393
    truncate = "truncate table " ..
     table_info.name
    -- item 2394
    exec(truncate)
    -- item 2397
    if table_info.name == "creds" then
        -- item 2623
        sql = build_full_insert_sql(
            table_info
        )
        for _, row in ipairs(rows) do
            -- item 2409
            user_id = row[1]
            cred = row[2]
            -- item 2419
            value = encode_cred(cred)
            -- item 2420
            exec_arr(
                sql,
                {user_id, value}
            )
        end
    else
        -- item 2568
        inserter = inserter_machine()
        inserter:init(table_info)
        for _, row in ipairs(rows) do
            -- item 2567
            inserter:next(row)
        end
        -- item 2569
        inserter:finish()
    end
    -- item 2571
    count = #rows
    -- item 2401
    log.info("Table " ..
      table_info.name ..
      " imported: " .. 
      tostring(count) ..
      " rows")
end

function index_exists(table_name, index_name)
    local count, rows, sql
    -- item 1596
    sql = "select count(*) count " ..
      "from information_schema.statistics " .. 
      "where table_schema = '" ..
      module.db ..
      "' and table_name = '" ..
      table_name ..
      "' and index_name = '" ..
      table_name .. "_" ..
      index_name .. "'"
    -- item 1597
    rows = exec(sql)
    -- item 1598
    count = rows[1][1].count
    -- item 1599
    return count > 0
end

function init_database()
    local info
    -- item 1246
    log.info("Init MySQL connector")
    -- item 1240
    create_database()
    -- item 1245
    create_pool()
    -- item 1241
    build_schema()
    for _, name in ipairs(module.table_list) do
        -- item 1249
        info = module.tables[name]
        -- item 1244
        create_table(info)
    end
    -- item 1247
    log.info("MySQL database initialized")
end

function insert_many(self)
    local count, sql, values
    -- item 2612
    count = #self.rows
    -- item 2611
    sql = build_full_insert_sql_many(
        self.table_info,
        count
    )
    -- item 2621
    --log.info(sql .. " == " ..
    -- tostring(count))
    -- item 2615
    values = {}
    for _, row in ipairs(self.rows) do
        -- item 2616
        utils.add_range(
            values,
            row
        )
    end
    -- item 2617
    exec_arr(
        sql,
        values
    )
    -- item 2565
    self.rows = {}
end

function insert_row(table_name, ...)
    local sql, table_info
    -- item 1739
    table_info = get_table(
        table_name
    )
    -- item 1738
    sql = build_insert_sql(
    	table_info,
    	...
    )
    -- item 1740
    return exec(sql, ...)
end

function insert_row_ai(table_name, ...)
    local connection, connector, result, row, sql, sql2, table_info, tuples
    -- item 1905
    table_info = get_table(
        table_name
    )
    -- item 1904
    sql = build_insert_sql(
    	table_info,
    	...
    )
    -- item 1907
    sql2 = "select LAST_INSERT_ID() id"
    -- item 2053
    connector = get_connector()
    connection = connector:connect()
    -- item 2049
    if module.verbose then
        -- item 2048
        log.info(sql)
    end
    -- item 2343
    tuples = exec_arr_kernel(
        connection,
        sql,
        {...}
    )
    -- item 2059
    if module.verbose then
        -- item 2054
        log.info("status: " .. tostring(status))
    end
    -- item 2062
    result = connection:execute(sql2)
    -- item 2063
    row = result[1][1]
    -- item 2065
    connector:disconnect()
    -- item 2064
    return row.id
end

function inserter_machine_Created_default(self, msg)
    -- item 2518
    self.state = "Created"
end

function inserter_machine_Created_init(self, msg)
    -- item 2536
    self.table_info = msg
    self.rows = {}
    -- item 2509
    self.state = "Normal"
end

function inserter_machine_Normal_finish(self, msg)
    -- item 2539
    if #self.rows == 0 then
        
    else
        -- item 2566
        insert_many(self)
    end
    -- item 2526
    self.state = nil
end

function inserter_machine_Normal_next(self, msg)
    -- item 2543
    table.insert(
        self.rows,
        msg
    )
    -- item 2544
    if #self.rows >= batch_size then
        -- item 2547
        insert_many(self)
    end
    -- item 2520
    self.state = "Normal"
end

function invoke_no_throw(action, description)
    -- item 1057
    local ok, result = pcall(action)
    -- item 1058
    if ok then
        -- item 1062
        return result
    else
        -- item 1061
        log.error(
          "error: "
          .. tostring(description)
          .. tostring(result)
        )
        -- item 1064
        clean_up()
        -- item 1063
        return nil
    end
end

function item_count()
    -- item 779
    return get_count(
        "items"
    )
end

function item_delete(space_id, folder_id, item_id)
    -- item 2137
    delete_row(
        "items",
        space_id,
        folder_id,
        item_id
    )
end

function item_get(space_id, folder_id, item_id)
    local item
    -- item 2138
    item = get_row_by_pk(
        "items",
        space_id,
        folder_id,
        item_id
    )
    -- item 304
    if item then
        -- item 308
        return item[4]
    else
        -- item 307
        return nil
    end
end

function item_get_by_folder(space_id, folder_id)
    -- item 2139
    return get_rows_by_column2(
        "items",
        "space_id",
        space_id,
        "folder_id",
        folder_id
    )
end

function item_insert(space_id, folder_id, item_id, idata)
    -- item 2152
    insert_row(
        "items",
        space_id,
        folder_id,
        item_id,
        idata
    )
end

function item_update(space_id, folder_id, item_id, idata)
    -- item 2153
    replace_row(
        "items",
        space_id,
        folder_id,
        item_id,
        idata
    )
end

function license_delete(id)
    -- item 1888
    delete_row(
        "licenses",
        id
    )
end

function license_get(id)
    local data, row
    -- item 1889
    row = get_row_by_pk(
        "licenses",
        id
    )
    -- item 712
    if row then
        -- item 709
        data = row[2]
        -- item 710
        return data
    else
        -- item 711
        return nil
    end
end

function license_insert(data)
    local id
    -- item 2066
    id = insert_row_ai(
        "licenses",
        data
    )
    -- item 2346
    return id
end

function license_update(id, data)
    -- item 1890
    replace_row(
        "licenses",
        id,
        data
    )
end

function make(parent, tag, text)
    local element
    -- item 2722
    element = {
        tag = tag,
        text = text,
        children = {}
    }
    -- item 2730
    if parent then
        -- item 2733
        table.insert(
            parent.children,
            element
        )
    end
    -- item 2734
    return element
end

function make_column_line(field, pk)
    local is_null, type
    local _sw15470000_ = 0
    -- item 15470000
    _sw15470000_ = field.type
    -- item 15470001
    if _sw15470000_ == "str" then
        -- item 1558
        type = "varchar(255)"
        -- item 1555
        if pk[field.name] then
            -- item 1561
            is_null = " not null"
        else
            -- item 1562
            is_null = ""
        end
        -- item 1563
        return field.name ..
         " " ..
         type ..
         is_null
    else
        -- item 15470002
        if _sw15470000_ == "int" then
            -- item 1559
            type = "int"
            -- item 1555
            if pk[field.name] then
                -- item 1561
                is_null = " not null"
            else
                -- item 1562
                is_null = ""
            end
            -- item 1563
            return field.name ..
             " " ..
             type ..
             is_null
        else
            -- item 15470003
            if _sw15470000_ == "json" then
                -- item 1560
                type = "varchar(4000)"
                -- item 1555
                if pk[field.name] then
                    -- item 1561
                    is_null = " not null"
                else
                    -- item 1562
                    is_null = ""
                end
                -- item 1563
                return field.name ..
                 " " ..
                 type ..
                 is_null
            else
                -- item 15470004
                if _sw15470000_ == "auto" then
                    
                else
                    -- item 15470005
                    error(_sw15470000_)
                end
                -- item 1567
                return field.name ..
                 " bigint not null auto_increment"
            end
        end
    end
end

function make_indent(depth)
    local indent_chars
    -- item 2749
    indent_chars = utils.repeat_value(
        "    ",
        depth
    )
    -- item 2750
    return utils.join(
        indent_chars,
        ""
    )
end

function make_index(table_info, index)
    local columns, sql
    -- item 1588
    if index_exists(table_info.name, index.name) then
        
    else
        -- item 1581
        if index.unique then
            -- item 1580
            sql = "create unique"
        else
            -- item 1584
            sql = "create"
        end
        -- item 1586
        columns = utils.join(
            index.columns,
            ", "
        )
        -- item 1585
        sql = sql ..
          " index " ..
          table_info.name ..
          "_" ..
          index.name ..
          " on " ..
          table_info.name ..
          " (" ..
          columns ..
          ")"
        -- item 1587
        exec(sql)
    end
end

function make_pk_line(table_info)
    local columns
    -- item 1573
    columns = utils.join(
        table_info.pk,
        ", "
    )
    -- item 1574
    return "constraint pk_" ..
      table_info.name ..
      " primary key (" ..
      columns ..
      ")"
end

function make_schema()
    local tables
    -- item 1447
    tables = {}
    -- item 1449
    add_table(
    	"users",
    	{
    		{"user_id", "str"},
    		{"email", "str"},
    		{"data", "json"}
    	},
    	{"user_id"},
    	create_index("by_email", {"email"}, true),
    	tables
    )
    -- item 1450
    add_simple_table(
        "creds",
        "user_id",
        tables
    )
    -- item 1454
    add_simple_table(
        "usettings",
        "user_id",
        tables
    )
    -- item 1455
    add_simple_table(
        "spaces",
        "space_id",
        tables
    )
    -- item 1451
    add_table(
    	"folders",
    	{
    		{"space_id", "str"},
    		{"folder_id", "str"},
    		{"data", "json"}
    	},
    	{"space_id", "folder_id"},
    	nil,
    	tables
    )
    -- item 1452
    add_table(
    	"items",
    	{
    		{"space_id", "str"},
    		{"folder_id", "str"},
    		{"item_id", "str"},
    		{"data", "json"}
    	},
    	{"space_id", "folder_id", "item_id"},
    	nil,
    	tables
    )
    -- item 1456
    add_table(
    	"recent",
    	{
    		{"space_id", "str"},
    		{"folder_id", "str"},
    		{"user_id", "str"},
    		{"data", "json"}
    	},
    	{"space_id", "folder_id", "user_id"},
    	create_index("by_user", {"user_id"}, false),
    	tables
    )
    -- item 2421
    add_table(
    	"rights",
    	{
    		{"space_id", "str"},
    		{"user_id", "str"},
    		{"access", "str"},
    		{"data", "json"}
    	},
    	{"space_id", "user_id", "access"},
    	create_index("by_user", {"user_id"}, false),
    	tables
    )
    -- item 2500
    add_table(
    	"trash",
    	{
    		{"space_id", "str"},
    		{"folder_id", "str"},
    		{"data", "json"}
    	},
    	{"space_id", "folder_id"},
    	nil,
    	tables
    )
    -- item 2624
    add_table(
    	"folder_tree",
    	{
    		{"space_id", "str"},
    		{"folder_id", "str"},
    		{"parent_id", "str"},
    		{"data", "json"}
    	},
    	{"space_id", "folder_id"},
    	create_index("by_parent", {"space_id", "parent_id"}, false),
    	tables
    )
    -- item 1448
    return tables
end

function payment_delete(payment_id)
    -- item 578
    delete_row(
        "payments",
        payment_id
    )
end

function payment_get_by_user(user_id)
    -- item 2105
    return get_rows_by_column(
        "payments",
        "user_id",
        user_id
    )
end

function payment_insert(user_id, payment)
    -- item 2106
    return insert_row_ai(
        "payments",
        user_id,
        payment
    )
end

function print_element(element)
    local tag, text
    -- item 2764
    text = element.text or ""
    tag = element.tag
    -- item 2765
    return "<" .. tag .. ">" ..
      text ..
      "</" .. tag .. ">"
end

function print_params(args)
    for _, arg in ipairs(args) do
        -- item 2211
        print(arg)
    end
end

function print_rows(result)
    local rows
    -- item 2200
    if result then
        -- item 2188
        rows = result[1]
        -- item 2202
        if (rows) and (not (#rows == 0)) then
            for _, row in ipairs(rows) do
                for key, value in pairs(row) do
                    -- item 2197
                    print(tostring(key) .. ": " .. tostring(value))
                end
                -- item 2198
                print("-----")
            end
        else
            -- item 2192
            print("no rows")
        end
    else
        -- item 2192
        print("no rows")
    end
end

function print_schema(filename)
    local lines, tables
    -- item 2660
    tables = make_schema()
    -- item 2661
    lines = {}
    for _, table in ipairs(tables) do
        -- item 2662
        print_table(table, lines)
    end
    -- item 2665
    write_lines(lines, filename)
end

function print_table(table, lines)
    -- item 2693
    h2(table.name, lines)
    -- item 2695
    h3("Columns", lines)
    -- item 2698
    write_columns(table.fields, lines)
    -- item 2696
    h3("Primary key", lines)
    -- item 2697
    write_pk(table.pk, lines)
    -- item 2699
    h3("Indexes", lines)
    -- item 2700
    write_indexes(table.indexes, lines)
end

function recent_delete(space_id, folder_id, user_id)
    -- item 389
    delete_row(
        "recent",
        space_id,
        folder_id,
        user_id
    )
end

function recent_get_by_folder(space_id, folder_id)
    -- item 2155
    return get_rows_by_column2(
        "recent",
        "space_id",
        space_id,
        "folder_id",
        folder_id
    )
end

function recent_get_by_user(user_id)
    -- item 2156
    return get_rows_by_column(
        "recent",
        "user_id",
        user_id
    )
end

function recent_upsert(space_id, folder_id, user_id, data)
    -- item 2154
    replace_row(
        "recent",
        space_id,
        folder_id,
        user_id,
        data
    )
end

function release_connection(connector)
    -- item 1115
    if connector.trans then
        
    else
        -- item 1113
        module.pool:put(
            connector.connection
        )
        -- item 1114
        connector.connection = nil
    end
end

function repeat_questions(count)
    -- item 2610
    return repeat_with_comma(
        "?",
        count
    )
end

function repeat_with_comma(what, count)
    local qs
    -- item 1722
    qs = utils.repeat_value(
        what,
        count
    )
    -- item 1724
    return utils.join(
        qs,
        ", "
    )
end

function replace_row(table_name, ...)
    local sql, table_info, values
    -- item 1750
    table_info = get_table(
        table_name
    )
    -- item 1749
    sql, values = build_replace_sql(
    	table_info,
    	...
    )
    -- item 1751
    exec_arr(sql, values)
end

function rights_delete(space_id, user_id, access)
    -- item 2433
    delete_row(
        "rights",
        space_id,
        user_id,
        access
    )
end

function rights_delete_by_space(space_id)
    -- item 2457
    exec_arr(
        "delete from rights where space_id = ?",
        {space_id}
    )
end

function rights_delete_by_user(user_id)
    -- item 2463
    exec_arr(
        "delete from rights where user_id = ?",
        {user_id}
    )
end

function rights_get_by_space(space_id)
    -- item 2439
    return get_rows_by_column(
        "rights",
        "space_id",
        space_id
    )
end

function rights_get_by_space_user(space_id, user_id)
    -- item 2451
    return get_rows_by_column2(
        "rights",
        "space_id",
        space_id,
        "user_id",
        user_id
    )
end

function rights_get_by_user(user_id)
    -- item 2445
    return get_rows_by_column(
        "rights",
        "user_id",
        user_id
    )
end

function rights_insert(space_id, user_id, access, data)
    -- item 2427
    replace_row(
        "rights",
        space_id,
        user_id,
        access,
        data
    )
end

function rollback()
    local connector
    -- item 2038
    connector = get_connector()
    -- item 2037
    connector:rollback()
end

function run_in_fiber(action, description)
    -- item 1071
    local safe_action = function()
    	invoke_no_throw(action, description)
    end
    -- item 1070
    fiber.create(safe_action)
end

function scheduled_delete(agreement_id)
    -- item 2112
    delete_row(
        "scheduled",
        agreement_id
    )
end

function scheduled_get(agreement_id)
    local row
    -- item 2113
    row = get_row_by_pk(
        "scheduled",
        agreement_id
    )
    -- item 642
    if row then
        -- item 646
        return row[2]
    else
        -- item 645
        return nil
    end
end

function scheduled_get_all()
    -- item 2114
    return get_all_rows(
        "scheduled"
    )
end

function scheduled_upsert(agreement_id, data)
    -- item 2115
    replace_row(
        "scheduled",
        agreement_id,
        data
    )
end

function serialize_params(args)
    -- item 2229
    return utils.map(
        args,
        table_to_json
    )
end

function session_count()
    -- item 2271
    return sessions:count()
end

function session_delete(session_id)
    -- item 2255
    sessions:delete(
        {session_id}
    )
end

function session_get(session_id)
    -- item 2249
    return sessions:get(
        {session_id}
    )
end

function session_get_by_user(user_id)
    -- item 2243
    return sessions.index.by_user:select(user_id)
end

function session_insert(session_id, user_id, sdata)
    -- item 2261
    sessions:insert(
        {session_id, user_id, sdata}
    )
end

function session_update(session_id, user_id, sdata)
    -- item 2267
    sessions:replace{session_id, user_id, sdata}
end

function space_count()
    -- item 2157
    return get_count(
        "spaces"
    )
end

function space_delete(space_id)
    -- item 2158
    delete_row(
        "spaces",
        space_id
    )
end

function space_get(space_id)
    local space
    -- item 2159
    space = get_row_by_pk(
        "spaces",
        space_id
    )
    -- item 340
    if space then
        -- item 339
        return space[2]
    else
        -- item 343
        return nil
    end
end

function space_get_all()
    -- item 2160
    return get_all_rows(
        "spaces"
    )
end

function space_insert(space_id, sdata)
    -- item 2161
    insert_row(
        "spaces",
        space_id,
        sdata
    )
end

function space_update(space_id, sdata)
    -- item 2162
    replace_row(
        "spaces",
        space_id,
        sdata
    )
end

function stats_get(req, session, headers)
    local diagrams, users
    -- item 559
    local dia_count = 0
    for key, tuple in folders:pairs() do
        -- item 562
        local fdata = tuple[3]
        -- item 563
        if fdata.type == "folder" then
            
        else
            -- item 566
            dia_count = dia_count + 1
        end
    end
    -- item 556
    local rdata = {
    	users = users:count(),
    	diagrams = dia_count
    }
    -- item 554
    return rdata
end

function table_to_json(value)
    -- item 2224
    if type(value) == "table" then
        -- item 2227
        return json.encode(value)
    else
        -- item 2228
        return value
    end
end

function transaction_delete(id)
    -- item 689
    delete_row(
        "transactions",
        id
    )
end

function transaction_get(id)
    local data, row, user_id
    -- item 2116
    row = get_row_by_pk(
        "transactions",
        id
    )
    -- item 659
    if row then
        -- item 664
        id = row[1]
        user_id = row[2]
        data = row[3]
        data.user_id = user_id
        data.id = id
        -- item 665
        return data
    else
        -- item 662
        return nil
    end
end

function transaction_get_by_user(user_id)
    -- item 2117
    return get_rows_by_column(
        "transactions",
        "user_id",
        user_id
    )
end

function transaction_insert(id, user_id, data)
    -- item 2118
    insert_row(
        "transactions",
        id,
        user_id,
        data
    )
end

function transaction_update(id, user_id, data)
    -- item 2119
    replace_row(
        "transactions",
        id,
        user_id,
        data
    )
end

function trash_delete(space_id, folder_id)
    -- item 2499
    delete_row(
        "trash",
        space_id,
        folder_id
    )
end

function trash_get_by_space(space_id)
    -- item 2487
    return get_rows_by_column(
        "trash",
        "space_id",
        space_id
    )
end

function trash_insert(space_id, folder_id)
    -- item 2493
    insert_row(
        "trash",
        space_id,
        folder_id,
        {}
    )
end

function update_one(table_name, field, ...)
    local sql, table_info, where
    -- item 1860
    table_info = get_table(
        table_name
    )
    -- item 1882
    where = build_pk_where_dumb(
        table_info
    )
    -- item 1862
    sql = "update " ..
      table_name ..
      " set " ..
      field ..
      " = ? " ..
      where
    -- item 1863
    exec(sql, ...)
end

function usecret_delete(user_id)
    -- item 2172
    delete_row(
        "usecrets",
        user_id
    )
end

function usecret_get(user_id)
    local row
    -- item 2170
    row = get_row_by_pk(
        "usecrets",
        user_id
    )
    -- item 530
    if row then
        -- item 534
        return row[2]
    else
        -- item 533
        return nil
    end
end

function usecret_upsert(user_id, cred)
    -- item 2171
    replace_row(
        "usecrets",
        user_id,
        cred
    )
end

function user_count()
    -- item 2175
    return get_count(
        "users"
    )
end

function user_delete(user_id)
    -- item 2176
    delete_row(
        "users",
        user_id
    )
end

function user_get(user_id)
    -- item 2177
    return get_row_by_pk(
        "users",
        user_id
    )
end

function user_get_all()
    -- item 2178
    return get_all_rows(
        "users"
    )
end

function user_get_by_email(email)
    -- item 2179
    return get_row_by_column(
        "users",
        "email",
        email
    )
end

function user_get_email(user_id)
    local user
    -- item 2180
    user = get_row_by_pk(
        "users",
        user_id
    )
    -- item 420
    if user then
        -- item 419
        return user[2]
    else
        -- item 423
        return nil
    end
end

function user_insert(id, email, data)
    -- item 2181
    insert_row(
        "users",
        id,
        email,
        data
    )
end

function user_update(id, email, data)
    -- item 2182
    replace_row(
        "users",
        id,
        email,
        data
    )
end

function usettings_delete(user_id)
    -- item 2169
    delete_row(
        "usettings",
        user_id
    )
end

function usettings_get(user_id)
    local row
    -- item 2173
    row = get_row_by_pk(
        "usettings",
        user_id
    )
    -- item 402
    if row then
        -- item 406
        return row[2]
    else
        -- item 405
        return nil
    end
end

function usettings_upsert(user_id, data)
    -- item 2174
    replace_row(
        "usettings",
        user_id,
        data
    )
end

function write_columns(columns, lines)
    local table, tr
    -- item 2787
    table = make(nil, "table", nil)
    -- item 2791
    tr = make(table, "tr", nil)
    -- item 2792
    make(tr, "th", "Column")
    make(tr, "th", "Data type")
    for _, field in ipairs(columns) do
        -- item 2793
        tr = make(table, "tr", nil)
        -- item 2794
        make(tr, "td", field.name)
        make(tr, "td", field.type)
    end
    -- item 2788
    element_to_lines(table, 0, lines)
end

function write_indexes(indexes, lines)
    local columns, element, table, tr
    -- item 2809
    if #indexes == 0 then
        -- item 2812
        element = make(nil, "p", "No indexes")
        -- item 2813
        element_to_line(element, lines)
    else
        -- item 2800
        table = make(nil, "table", nil)
        -- item 2804
        tr = make(table, "tr", nil)
        -- item 2805
        make(tr, "th", "Name")
        make(tr, "th", "Columns")
        make(tr, "th", "Unique")
        for _, index in ipairs(indexes) do
            -- item 2806
            tr = make(table, "tr", nil)
            -- item 2808
            columns = utils.join(
                index.columns,
                ", "
            )
            -- item 2807
            make(tr, "td", index.name)
            make(tr, "td", columns)
            make(tr, "td", tostring(index.unique))
        end
        -- item 2801
        element_to_lines(table, 0, lines)
    end
end

function write_lines(lines, filename)
    local data
    -- item 2674
    data = utils.join(
        lines,
        "\n"
    )
    -- item 2673
    utils.write_all_bytes(
        filename,
        data
    )
end

function write_pk(columns, lines)
    local columns_str, element
    -- item 2779
    columns_str = utils.join(
        columns,
        ", "
    )
    -- item 2780
    element = make(
        nil,
        "p",
        columns_str
    )
    -- item 2781
    element_to_line(
        element,
        lines
    )
end


function connector_machine()
    local obj = {}
    obj.type_name = "connector_machine"
    obj.state = "Idle"
    obj.begin = function(self, msg)
        local _state_ = self.state
        if _state_ == "Idle" then
            return connector_machine_Idle_begin(self, msg)
        elseif _state_ == "Connected" then
            return connector_machine_Connected_begin(self, msg)
        elseif _state_ == "Transaction" then
            return connector_machine_Transaction_begin(self, msg)
        end
        return nil
    end
    obj.clean_up = function(self, msg)
        local _state_ = self.state
        if _state_ == "Connected" then
            return connector_machine_Connected_clean_up(self, msg)
        elseif _state_ == "Transaction" then
            return connector_machine_Transaction_clean_up(self, msg)
        end
        return nil
    end
    obj.commit = function(self, msg)
        local _state_ = self.state
        if _state_ == "Idle" then
            return connector_machine_Idle_commit(self, msg)
        elseif _state_ == "Connected" then
            return connector_machine_Connected_commit(self, msg)
        elseif _state_ == "Transaction" then
            return connector_machine_Transaction_commit(self, msg)
        end
        return nil
    end
    obj.connect = function(self, msg)
        local _state_ = self.state
        if _state_ == "Idle" then
            return connector_machine_Idle_connect(self, msg)
        elseif _state_ == "Connected" then
            return connector_machine_Connected_connect(self, msg)
        elseif _state_ == "Transaction" then
            return connector_machine_Transaction_connect(self, msg)
        end
        return nil
    end
    obj.disconnect = function(self, msg)
        local _state_ = self.state
        if _state_ == "Connected" then
            return connector_machine_Connected_disconnect(self, msg)
        elseif _state_ == "Transaction" then
            return connector_machine_Transaction_disconnect(self, msg)
        end
        return nil
    end
    obj.rollback = function(self, msg)
        local _state_ = self.state
        if _state_ == "Idle" then
            return connector_machine_Idle_rollback(self, msg)
        elseif _state_ == "Connected" then
            return connector_machine_Connected_rollback(self, msg)
        elseif _state_ == "Transaction" then
            return connector_machine_Transaction_rollback(self, msg)
        end
        return nil
    end
    return obj
end

function inserter_machine()
    local obj = {}
    obj.type_name = "inserter_machine"
    obj.state = "Created"
    obj.finish = function(self, msg)
        local _state_ = self.state
        if _state_ == "Created" then
            return inserter_machine_Created_default(self, msg)
        elseif _state_ == "Normal" then
            return inserter_machine_Normal_finish(self, msg)
        end
        return nil
    end
    obj.init = function(self, msg)
        local _state_ = self.state
        if _state_ == "Created" then
            return inserter_machine_Created_init(self, msg)
        end
        return nil
    end
    obj.next = function(self, msg)
        local _state_ = self.state
        if _state_ == "Created" then
            return inserter_machine_Created_default(self, msg)
        elseif _state_ == "Normal" then
            return inserter_machine_Normal_next(self, msg)
        end
        return nil
    end
    return obj
end

init_database()


return {
folder_get = folder_get,
folder_insert = folder_insert,
folder_delete = folder_delete,
folder_get_by_space = folder_get_by_space,
folder_update = folder_update,
folder_get_all = folder_get_all,

item_get = item_get,
item_update = item_update,
item_insert = item_insert,
item_delete = item_delete,
item_get_by_folder = item_get_by_folder,

space_get = space_get,
space_insert = space_insert,
space_delete = space_delete,
space_get_all = space_get_all,
space_update = space_update,

usettings_upsert = usettings_upsert,
usettings_get = usettings_get,
usettings_delete = usettings_delete,

recent_upsert = recent_upsert,
recent_get_by_folder = recent_get_by_folder,
recent_get_by_user = recent_get_by_user,
recent_delete = recent_delete,

begin = begin,
commit = commit,
rollback = rollback,
clean_up = clean_up,

user_get_email = user_get_email,
user_get = user_get,
user_insert = user_insert,
user_delete = user_delete,
user_get_by_email = user_get_by_email,
user_update = user_update,
user_get_all = user_get_all,

session_get_by_user = session_get_by_user,
session_get = session_get,
session_delete = session_delete,
session_insert = session_insert,
session_update = session_update,

usecret_get = usecret_get,
usecret_upsert = usecret_upsert,
usecret_delete = usecret_delete,

cred_get = cred_get,
cred_upsert = cred_upsert,
cred_delete = cred_delete,

stats_get = stats_get,

payment_get_by_user = payment_get_by_user,
payment_delete = payment_delete,
payment_insert = payment_insert,

agreement_get = agreement_get,
agreement_delete = agreement_delete,
agreement_get_by_order_ref = agreement_get_by_order_ref,
agreement_insert = agreement_insert,
agreement_update = agreement_update,
agreement_update_order = agreement_update_order,
agreement_update_data = agreement_update_data,

transaction_get = transaction_get,
transaction_insert = transaction_insert,
transaction_get_by_user = transaction_get_by_user,
transaction_update = transaction_update,
transaction_delete = transaction_delete,

license_insert = license_insert,
license_delete = license_delete,
license_get = license_get,
license_update = license_update,

coupon_insert = coupon_insert,
coupon_get = coupon_get,
coupon_update = coupon_update,

scheduled_delete = scheduled_delete,
scheduled_get = scheduled_get,
scheduled_upsert = scheduled_upsert,
scheduled_get_all = scheduled_get_all,

item_count = item_count,
space_count = space_count,
user_count = user_count,
session_count = session_count,

make_schema = make_schema,
invoke_no_throw = invoke_no_throw,
run_in_fiber = run_in_fiber,

rights_insert = rights_insert,
rights_delete = rights_delete,
rights_get_by_space = rights_get_by_space,
rights_get_by_user = rights_get_by_user,
rights_get_by_space_user = rights_get_by_space_user,
rights_delete_by_space = rights_delete_by_space,
rights_delete_by_user = rights_delete_by_user,

trash_get_by_space = trash_get_by_space,
trash_insert = trash_insert,
trash_delete = trash_delete,

folder_tree_upsert = folder_tree_upsert,
folder_tree_delete = folder_tree_delete,
folder_tree_get_by_parent = folder_tree_get_by_parent,
folder_tree_get = folder_tree_get,

from_tara_to_mysql = from_tara_to_mysql,
print_schema = print_schema

}
