Skip to content

MySQL

Provides a client-side api to the EZ query methods of the server-side MySQL module. For more complex data handling, you must provide an api on the server-side.

Database Required

Before you can use the MySQL module, you will need to create a MySQL database. See the Administration section for more information on connecting to your database.

select

Select multiple records from a database table.

core.mysql.select(query_tbl, listener)

Parameters

Name Description Type Required
query_tbl The query parameters for the call. Table Y
listener The api listener callback function. Function Y

Query Table Keys

Name Description Type Required
db The database to run the query against. String Y
tbl Name of the table to operate on. String Y
columns Array of columns to select as strings. Table N
where Any additional WHERE clause to apply. String or Table N
orderby The sorting attributes. See Orderby below. Table N
limit Limit the records returned. See Limit below. Number or Table N
distinct Filter out duplicate column values. Default: false Boolean N

Orderby

The orderby key should be a table filled with column = direction pairs. The direction can be either "ASC" for ascending order or "DESC" for descending order.

Limit

To limit the rows returned, supply a number value to the limit key. To offset the limit, supply a table array of number values. For example, to return rows 6-15: limit = {5, 10}.

Event Response

On success, the result will contain a table array of records.

Example

Using the "app" database, select all records from the "users" table.

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    for i=1, #evt.result do
      print(evt.result[i].id)
    end
  end
end

local params = {
  db = "app",
  tbl = "users"
}

core.mysql.select(params, apiListener)

More Examples

See the server-side core.mysql.select method for more examples.

selectOne

Select and return a single record from a database table.

core.mysql.selectOne(query_tbl, listener)

Parameters

Name Description Type Required
query_tbl The query parameters for the call. Table Y
listener The api listener callback function. Function Y

Query Table Keys

Name Description Type Required
db The database to run the query against. String Y
tbl Name of the table to operate on. String Y
where The WHERE clause to apply. String or Table Y
columns Array of columns to select as strings. Table N

Event Response

On success, the result will contain a table.

Special Response

Unlike the select method, the result is returned as a single record as opposed to an array of records.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    print(evt.result.name)
  end
end

local params = {
  db = "app",
  tbl = "users",
  where = { user_id = 20 },
  columns = { "name" }
}

core.mysql.selectOne(params, apiListener)

selectBatch

Query multiple tables of a database and return the individual results in a keyed response.

core.mysql.selectBatch(batch_tbl, listener)

Parameters

Name Description Type Required
batch_tbl The batch parameters for the call (see below). Table Y
listener The api listener callback function. Function Y

Batch Table Keys

Name Description Type Required
db The database to run the query against. String Y
batch A table array of EZ Query select tables, excluding the db key. (see select). Each select table must also include a key property for the result response (see example below). Table Y

Event Response

On success, the result will be a keyed table with the results of each select query as a table array of records. If limit in any of the query entries is set to 1, then a single table with the record data is returned (not an array).

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    local bikes = evt.result.bikes --Array of "Bike" records
    local shoes = evt.result.shoes --Array of "Shoe" records
    local store = evt.result.store --Table "Store" record
  end
end

local batch_select = {
  {
    tbl = "products",
    where = { type = "Bike" },
    key = "bikes"
  },
  {
    tbl = "products",
    where = { type = "Shoes" },
    key = "shoes"
  },
  {
    tbl = "locations",
    where = { name = "Happy Toys" },
    limit = 1, --Return as non-array record
    key = "store"
  }
}

local params = {
  db = "store",
  batch = batch_select
}

core.mysql.selectBatch(params, apiListener)

Query Errors

If any of the queries in the batch result in an error, the results key for that particular query will contain an error key. Best practice is to check for this key before accessing the results.

-- Assuming batch call as shown in the example above

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    if evt.result.bikes.error then
      --an error occurred on this particular query
      print(evt.result.bikes.error)
    else
      --loop over the records
      for i=1, #evt.result.bikes do
        print(evt.result.bikes[i].name)
      end
    end
  end
end

selectMerge

Select from multiple databases and tables and return the results in a keyed table.

core.mysql.selectMerge(merge_tbl, listener)

Parameters

Name Description Type Required
merge_tbl The merge parameters for the call (see below). Table Y
listener The api listener callback function. Function Y

Merge Table Keys

Name Description Type Required
merge A table array of EZ Query select tables. (see select). Each select table should also include a key property for the result table (see example below). Table Y

Event Response

On success, the result will be a keyed table with the results of each select query. If limit in any of the query entries is set to 1, then a single table with the record data is returned (not an array). See Errors below.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    local locs = evt.result.locs

    --check for errors
    if evt.result.errors then
      for i=1, #evt.results.errors do
        local err_tbl = evt.results.error[i]
        print(err_tbl.db, err_tbl.error, err_tbl.index)
      end
    end
  end
end

local merge_dbs = {
  {
    db = "locations",
    tbl = "spots",
    key = "locs"
  },
  {
    db = "products",
    tbl = "parts",
    where = { part_id = 20 },
    key = "part"
  },
  {
    db = "stores",
    tbl = "toy",
    limit = 1, --Return as non-array record
    where = { name = "Happy Toys" },
    key = "store"
  }
}

core.mysql.selectMerge({ merge = merge_dbs }, apiListener)

Errors

If any of the database queries fail, the successful queries will still be returned in their respective key names. On failed queries, the result will also contain an errors key, containing a table array describing any errors.

Example Debug Response

result:
  errors:
  1:
    db: products
    error: Table 'products.parts' doesn't exist
    index: 2
    status: 1146
  locs:
  1:
    id: 1
    latitude: 80
    longitude: 200
    user_id: d23b8738-4d28-41ed-a967-98e83e855a38
  2:
    id: 3
    latitude: -64
    longitude: 200
    user_id: d23b8738-4d28-41ed-a967-98e83e855a39
  store:
    name = Happy Toys
    city = San Diego

selectCount

Get a record count based on passed in query.

core.mysql.selectCount(count_tbl, listener)

Parameters

Name Description Type Required
count_tbl The count parameters for the call (see below). Table Y
listener The api listener callback function. Function Y

Count Table Keys

Name Description Type Required
db The database to run the count query against. String Y
tbl Name of the table to operate with. String Y
where The WHERE clause to apply. String or Table N
column The column to use as the counting key. Defaults to "id". String N

If the where key is not included, the result is the total records in the provided table.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    local count = evt.result.count
    print("Total red toys:", count)
end

core.mysql.selectCount({
  db = "products",
  tbl = "toys",
  where = { color = "Red" }
}, apiListener)

insert

Insert a single record into a database table.

core.mysql.insert(query_tbl, listener)

Parameters

Name Description Type Required
query_tbl The query parameters for the call. Table Y
listener The api listener callback function. Function Y

Query Table Keys

Name Description Type Required
db The database to run the query against. String Y
tbl Name of the table to operate on. String Y
values A table of column = value pairs. Table Y

Important

Strings in the values tables are run through the mysql.escape method. Do not double-escape values.

Event Response

On success, the result will contain the inserted record id as a number.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    print("insert id:", evt.result)
  end
end

local params = {
  db = "app",
  tbl = "users",
  values = {
    name = "Bobby",
    age = 34
  },
}

core.mysql.insert(params, apiListener)

insertMany

Insert records into a single table of a database in an optimized way.

core.mysql.insertMany(insert_tbl, listener)

Parameters

Name Description Type Required
insert_tbl The insert parameters table for the call (see below). Table Y
listener The api listener callback function. Function Y

Insert Table Keys

Name Description Type Required
db The database to run the inserts against. String Y
tbl Name of the table to operate on. String Y
records A table array of values tables from the insert method. Table Y

Important

Strings in the values tables are run through the mysql.escape method. Do not double-escape values.

Event Response

On success, the result will hold an indexed table array of tables containing either an id key; with the id of the newly created record, or an error key; containing the error string.

The response table is indexed the same order as the records table that was sent to the server.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    for i=1, #evt.result do
      local entry = evt.result[i]

      if entry.error then
        print("error in insert entry #"..i..": "..entry.error)
      else
        print("inserted record with id: "..entry.id.." for entry #"..i)
      end
    end
  end
end

local toys = {
  {
    name = "Car",
    color = "red"
  },
  {
    name = "Teddy Bear",
    color = "brown"
  }
}

local params = {
  db = "products",
  tbl = "toys",
  records = toys
}

core.mysql.insertMany(params, apiListener)

insertBatch

Insert records into multiple tables of a database in an optimized way.

core.mysql.insertBatch(batch_tbl, listener)

Parameters

Name Description Type Required
batch_tbl The batch parameters table for the call (see below). Table Y
listener The api listener callback function. Function Y

Batch Table Keys

Name Description Type Required
db The database to run the batch against. String Y
batch A table array of tables with the tbl and values keys from the insert method. Table Y

Important

Strings in the values tables are run through the mysql.escape method. Do not double-escape values.

Event Response

On success, the result will hold an indexed table array of tables containing either an id key; with the id of the newly created record, or an error key; containing the error string.

The response table is indexed the same order as the batch table that was sent to the server.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    for i=1, #evt.result do
      local entry = evt.result[i]

      if entry.error then
        print("error in insert entry #"..i..": "..entry.error)
      else
        print("inserted record with id: "..entry.id.." for entry #"..i)
      end
    end
  end
end

local batch_insert = {
  {
    tbl = "shoes"
    values = {
      name = "Adidas",
      size = 12
    }
  },
  {
    tbl = "toys",
    values = {
      name = "Car",
      age_group = 10
    }
  },
  {
    tbl = "toys",
    values = {
      name = "Bear",
      age_group = 5,
      color = "Brown"
    }
  }
}

local params = {
  db = "products",
  batch = batch_insert
}

core.mysql.insertBatch(params, apiListener)

update

Update record(s) in a database table.

core.mysql.update(query_tbl, listener)

Parameters

Name Description Type Required
query_tbl The query parameters for the call. Table Y
listener The api listener callback function. Function Y

Query Table Keys

Name Description Type Required
db The database to run the query against. String Y
tbl The name of the table to operate on. String Y
values A table of column = value pairs. Table Y
where Where the columns should be updated. String or Table N

Important

Strings in the values tables are run through the mysql.escape method. Do not double-escape values.

Event Response

On success, the result will contain the amount of records updated as a number.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    print("updated:", evt.result)
  end
end

local params = {
  db = "app",
  tbl = "users",
  values = {
    name = "Paco"
  },
  where = { name = "Bobby" }
}

core.mysql.update(params, apiListener)

updateMany

Update records in a single table of a database in an optimized way.

core.mysql.updateMany(update_tbl, listener)

Parameters

Name Description Type Required
update_tbl The update parameters table for the call (see below). Table Y
listener The api listener callback function. Function Y

Update Table Keys

Name Description Type Required
db The database to run the updates against. String Y
tbl Name of the table to operate on. String Y
update A table array of tables with the values and where keys from the update method. Table Y

Important

Strings in the values tables are run through the mysql.escape method. Do not double-escape values.

Event Response

On success, the result will hold an indexed table array of tables containing either an updated key; with the number of records updated, or an error key; containing the error string.

The response table is indexed the same order as the update table that was sent to the server.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    for i=1, #evt.result do
      local entry = evt.result[i]

      if entry.error then
        print("error in update entry #"..i..": "..entry.error)
      else
        print("updated "..entry.updated.." records for entry #"..i)
      end
    end
  end
end

local update_tbl = {
  {
    values = {
      name = "Nike"
    },
    where = { name = "Adidas" }
  },
  {
    values = {
      cost = "1.99"
    },
    where = { id = 3 }
  }
}

local params = {
  db = "products",
  tbl = "shoes",
  update = update_tbl
}

core.mysql.updateMany(params, apiListener)

updateBatch

Update records in multiple tables of a database in an optimized way.

core.mysql.updateBatch(batch_tbl, listener)

Parameters

Name Description Type Required
batch_tbl The batch parameters table for the call (see below). Table Y
listener The api listener callback function. Function Y

Batch Table Keys

Name Description Type Required
db The database to run the batch against. String Y
batch A table array of tables with the tbl, values and where keys from the update method. Table Y

Important

Strings in the values tables are run through the mysql.escape method. Do not double-escape values.

Event Response

On success, the result will hold an indexed table array of tables containing either an updated key; with the number of records updated, or an error key; containing the error string.

The response table is indexed the same order as the batch table that was sent to the server.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    for i=1, #evt.result do
      local entry = evt.result[i]

      if entry.error then
        print("error in update entry #"..i..": "..entry.error)
      else
        print("updated "..entry.updated.." records for entry #"..i)
      end
    end
  end
end

local batch_update = {
  {
    tbl = "shoes",
    values = {
      name = "Adidas"
    },
    where = { id = 3 }
  },
  {
    tbl = "toys",
    values = {
      name = "Raggedy Ann",
      gender = "female"
    },
    where = { name = "Raggedy Andy" }
  },
  {
    tbl = "toys",
    values = {
      company = "Tonka"
    },
    where = { id = 4 }
  }
}

local params = {
  db = "products",
  batch = batch_update
}

core.mysql.updateBatch(params, apiListener)

delete

Delete record(s) from a database table.

core.mysql.delete(query_tbl, listener)

Parameters

Name Description Type Required
query_tbl The query parameters table for the call (see below). Table Y
listener The api listener callback function. Function Y

Query Table Keys

Name Description Type Required
db The database to run the query against. String Y
tbl The name of the table to operate on. String Y
where A WHERE clause to limit deletions to. String or Table N
force Disables safety check for missing where key. Boolean N

Force Delete

To run the delete command without a where clause, you must set force to true.

Event Response

On success, the result will contain the amount of records deleted as a number.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    print("deleted:", evt.result)
  end
end

local params = {
  db = "app",
  tbl = "users",
  where = { id = 10 }
}

core.mysql.delete(params, apiListener)

Tip

See the server-side core.mysql.delete method for more examples.

deleteMany

Delete records from a single table in a database in an optimized way.

core.mysql.deleteMany(delete_tbl, listener)

Parameters

Name Description Type Required
delete_tbl The delete parameters table for the call (see below). Table Y
listener The api listener callback function. Function Y

Delete Table Keys

Name Description Type Required
db The database to run the deletes against. String Y
tbl Name of the table to operate on. String Y
delete A table array of tables with the where key from the delete method. Table Y

Event Response

On success, the result will hold an indexed table array of tables containing either a deleted key; with the number of records deleted, or an error key; containing the error string.

The response table is indexed the same order as the delete table that was sent to the server.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    for i=1, #evt.result do
      local entry = evt.result[i]

      if entry.error then
        print("error in delete entry #"..i..": "..entry.error)
      else
        print("deleted "..entry.deleted.." records for entry #"..i)
      end
    end
  end
end

local delete_tbl = {
  {
    where = { id = 34 }
  },
  {
    where = { color = "Red" }
  }
}

local params = {
  db = "products",
  tbl = "shoes",
  delete = delete_tbl
}

core.mysql.deleteMany(params, apiListener)

deleteBatch

Delete records from multiple tables of a database in an optimized way.

core.mysql.deleteBatch(batch_tbl, listener)

Parameters

Name Description Type Required
batch_tbl The batch parameters table for the call (see below). Table Y
listener The api listener callback function. Function Y

Batch Table Keys

Name Description Type Required
db The database to run the batch against. String Y
batch A table array of tables with the tbl and where keys from the delete method. Table Y

Event Response

On success, the result will hold an indexed table array of tables containing either a deleted key; with the number of records deleted, or an error key; containing the error string.

The response table is indexed the same order as the batch table that was sent to the server.

Example

local function apiListener( evt )
  if evt.error then
    print(evt.error)
  else
    for i=1, #evt.result do
      local entry = evt.result[i]

      if entry.error then
        print("error in delete entry #"..i..": "..entry.error)
      else
        print("deleted "..entry.deleted.." records for entry #"..i)
      end
    end
  end
end


local batch_delete = {
  {
    tbl = "toys",
    where = { id = 2 }
  },
  {
    tbl = "shoes",
    where = { type = "running" }
  }
}

local params = {
  db = "products",
  batch = batch_delete
}

core.mysql.deleteBatch(params, apiListener)

The WHERE Key

Many of the MySQL (and other) modules use a where key to specify the "WHERE" clause for a database query. Depending on what data type and structure you provide this key, a couple different things can happen automagically.

String Based

When passing a string to the where key, you are on your own to create a valid MySQL query string. The query string is interpreted as-is.

You never include the literal "WHERE" in the where key value.

Examples

where = "`color`='Red'"
where = "`kind`='Truck' AND `color`='Red'"
where = "`kind`='Truck' OR `kind`='Car'"

Table Based

The advantage of using a table based where key is that all of the values are properly formatted to make a valid and type-safe MySQL query.

Important

String values are automatically run through mysql.escape. Do not double-escape values.

To reproduce the three string based examples above as table based:

where = { color = "Red" }
where = { kind = "Truck", color = "Red" } --AND
where = { kind = { "Truck", "Car" } } --OR

Ordered Table Queries

With "ordered" query tables you can replicate some more complex queries:

where = "`color='Red' AND `model`='Ford' AND kind='Truck' OR kind='Car'"

To reproduce the query above, put the entries in a table array (order matters):

where = {
  { color = "Red", model = "Ford" },
  { kind = { "Truck", "Car" } }
}

For an all OR query like:

where = "`color='Red' OR `model`='Ford' OR kind='Truck' OR kind='Car'"

You can use an ordered table with a single entry:

where = {
  { color = { "Red" }, model = { "Ford" }, kind = { "Truck", "Car" } }
}

At this time multiple entries in an "ordered" where table are combined using 'AND', which may cause problems with more complicated queries, so you'll need to fall back to the string method.

Table type queries also do not support conditionals, so the following cannot be replicated with a table based query:

where = "`score` > 100"

Optimized Methods

When working with multiple entries per query, try to choose an optimized query method. The reason for this is due to the fact that each Coronium Client network request to the server requires opening a new database connection per call.

By using the optimized query methods, the Coronium Core server can take advantage of using cached database connections, providing lower overhead and better performance.

Most optimized query methods also make it easier to program your application logic, by grouping results and using less calls.

The following are optimized MySQL module methods:

  • selectBatch
  • selectMerge
  • insertMany
  • insertBatch
  • updateMany
  • updateBatch
  • deleteMany
  • deleteBatch

Network Timeout

Though rare, very large workloads may cause the Corona client to throw a network timeout error before you receive a reponse from the server. In these cases you can add a timeout parameter to the query_tbl table.

The Corona default network timeout is 30 seconds. This is an optional parameter.

Example

local function apiListener( evt )
  ...
end

local params = {
  db = "app",
  tbl = "users",
  timeout = 60
}

core.mysql.select(params, apiListener)

Server-Side Timeout

To adjust the MySQL server timeout for large queries, see MySQL Timeout.