SQL

Run complex sql queries and process data without writing any code

Connection

How to make connection to Mysql or Postgres using single json configuration

{
  "id": "sample-database-connection",
  "type": "sql",
  "driver": "mysql", //mysql|postgres
  "name": "Sample database name",
  "dns": "_databaseUsername_:_databasePassword_@tcp(example.com:3310)/_databaseName_?parseTime=true",
  "maxOpenConnections": 100,
  "connectionMaxLifetimeSec": 10,
  "maxIdleConnections": 30,
  "connectionMaxIdleTimeSec": 10
}

Select

Select non paginated data from database Fetch single or multiple items from database without using pagination

{
  "type": "sql-select",
  "id": "products-by-id",
  "connection": "sample-database-connection",
  "query": "SELECT * FROM `product` where id IN(:id)",
  "resultType": "list",
  "params": [
    {
      "name": "id",
      "type": "int",
      "required": true,
      "list": true,
      "default": [0]
    }
  ]
}

Select paginated

Fetch multiple items from database with build in pagination Select paginated data from database

{
  "type": "sql-select-paginated",
  "id": "products-paginated",
  "connection": "sample-database-connection",
  "query": "SELECT * FROM `product` limit :offset, :limit",
  "queryCount": "SELECT count(*) as c FROM `product`",
  "params": [
    {
      "name": "limit",
      "type": "int",
      "default": 10,
      "required": true
    },
    {
      "name": "page",
      "type": "int",
      "default": 1,
      "required": true
    }
  ]
}

Every sql-select-paginated query must contain (:page, :limit) or :offset params, they are special, created and calculated by the system

Query builder

Build complex query and exec statements based on external parameters Complex SQL query builder

{
  "type": "sql-builder",
  "id": "sample-query",
  "connection": "sample-database-connection",
  "file": "sample.js",
  "permissions": [
    "admin",
    "user"
  ],
  "public": true,
  "params": [
    {
      "name": "name",
      "required": true
    },
    {
      "name": "code",
      "required": true
    }
  ]
}

If you would like to select data without pagination

let query = "SELECT * FROM estates where `code` = :code limit 3"

builder.setQuery(query)
builder.setParams({ code: "EN", name: request.params.name})

If you would like to select data with pagination

let query = "SELECT * FROM estates where `code` = :code limit 3"
let queryCount = "SELECT count(*) as c FROM estate_type"

builder.setQuery(query)
builder.setCountQuery(queryCount)
builder.setParams({ code: "EN", name: request.params.name})

If you would like to run exec statement like update, delete, insert or any other

let queryExec = "Insert into `estate` (`player_id`, `deviceId`, `created_at`) VALUES (1, :name, NOW())"
builder.setParams({ code: "EN", name: request.params.name})
builder.setQueryExec(queryExec)

Insert

Insert statement Insert data without writing any code

{
  "type": "sql-insert",
  "id": "order-item-insert",
  "connection": "sample-database-connection",
  "table": "order_item",
  "selectAfterInsert": "SELECT product_id as productId, quantity FROM order_item where id = :lastInsertId",
  "params": [
    {
      "columnName": "order_id",
      "name": "orderId",
      "required": true
    },
    {
      "columnName": "product_id",
      "name": "productId",
      "required": true
    },
    {
      "columnName": "quantity",
      "name": "quantity",
      "required": true
    }
  ]
}

selectAfterInsert - query that will be run after insert, you could count total number of items in database and show it to the user, new parameter is available there :lastInsertId it is auto generated by apizilla, you can use other params too

required - required parameters must be provided, otherwise query won’t start, non required params will be omitted in insert

Update

Update data without writing any code

{
  "type": "sql-update",
  "id": "order-set-status-update",
  "connection": "sample-database-connection",
  "table": "order",
  "whereCondition": "`id` = :id",
  "params": [
    {
      "column": "status",
      "name": "status",
      "required": true
    },
    {
      "name": "id",
      "required": true
    },
    {
      "name": "createdAt",
      "column": "created_at",
      "sqlValue": "NOW()"
    }
  ]
}

column field is responsible for creating SET part of sql query, i.e UPDATE ... SET column = :paramName, if you skip it, then it won’t generate SET data. If you add column to id param in example below, you will end up with query like this

UPDATE `order` SET status = :status, id = :id, createdAt = NOW() WHERE id = :id

whereCondition - update conditions

Delete

Delete data without writing any code Delete statement

{
  "type": "sql-exec",
  "id": "client-delete",
  "connection": "sample-database-connection",
  "query": "DELETE FROM users WHERE id IN(:id) AND user_id = :currentUser",
  "params": [
    {
      "required": true,
      "name": "id"
    },
    {
      "name": "currentUser",
      "serverValue": "$.user.id",
      "required": true
    }
  ]
}

Transaction

Perform complex database transactions

{
  "type": "javascript",
  "id": "order-new",
  "file": "order-new.js",
  "public": true,
  "params": []
}
let orderId = uuid(),
    currentTransaction = transaction("sample-database-connection"),
    orderData = null;

try {
    orderData = currentTransaction.run("orders-insert", {
        "id": orderId,
        "amount": totalPrice,
        "currentUserId": 1,
    }).Data

    currentTransaction.run("order-item-insert", {
        "orderId": orderData.id,
        "productId": 1,
        "quantity": 1
    })

    currentTransaction.run("order-item-insert", {
        "orderId": orderData.id,
        "productId": 2,
        "quantity": 22
    })

    currentTransaction.commit()
} catch (e) {
    currentTransaction.rollback()
    throw {"error": e}
}

setStatusCode(200)
setResult({
    orderId: orderData.id
})

Sql security

All the sql queries are run as prepared statement

You cannot create prepare statement (with order as param) It won’t run properly!

{
  "type": "sql-select",
  "id": "player-list",
  "connection": "sample-database-connection",
  "query": "SELECT player.* FROM app.player where username is not null ORDER BY id :orderDirection",
  "resultType": "list",
  "params": [
    {
      "paramName": "orderDirection",
      "type": "string",
      "required": true
    }
  ]
}

Just use Query Builder

Params

Options you can use to define param

sqlValue - use database specific values like NOW()

Last modified April 16, 2024: content fix (a2d9b96)