
- Lua Tutorial
- Lua - Home
- Lua Basics
- Lua - Overview
- Lua - Environment
- Lua - Basic Syntax
- Lua - Comments
- Lua - Print Hello World
- Lua - Variables
- Lua - Data Types
- Lua - Operators
- Lua - Loops
- Lua - Generic For
- Lua - Decision Making
- Lua - Date and Time
- Lua Functions
- Lua - Functions
- Lua - Multiple Results
- Lua - Named Arguments
- Lua - Default/Optional Arguments
- Lua - Closures
- Lua - Uses of Closures
- Lua - Local Functions
- Lua - Anonymous Functions
- Lua - Functions in Table
- Lua - Proper Tail Calls
- Lua Strings
- Lua - Strings
- Lua - String Concatenation
- Lua - Loop Through String
- Lua - String to Int
- Lua - Split String
- Lua - Check String is NULL
- Lua Arrays
- Lua - Arrays
- Lua - Multi-dimensional Arrays
- Lua - Array Length
- Lua - Iterating Over Arrays
- Lua - Slicing Arrays
- Lua - Sorting Arrays
- Lua - Merging Arrays
- Lua - Sparse Arrays
- Lua - Searching Arrays
- Lua - Resizing Arrays
- Lua - Array to String Conversion
- Lua - Array as Stack
- Lua - Array as Queue
- Lua - Array with Metatables
- Lua - Immutable Arrays
- Lua - Shuffling Arrays
- Lua Iterators
- Lua - Iterators
- Lua - Stateless Iterators
- Lua - Stateful Iterators
- Lua - Built-in Iterators
- Lua - Custom Iterators
- Lua - Iterator Closures
- Lua - Infinite Iterators
- Lua - File Iterators
- Lua - Table Iterators
- Lua - Numeric Iterators
- Lua - Reverse Iterators
- Lua - Filter Iterators
- Lua - Range Iterators
- Lua - Chaining Iterators
- Lua Tables
- Lua - Tables
- Lua - Tables as Arrays
- Lua - Tables as Dictionaries
- Lua - Tables as Sets
- Lua - Table Length
- Lua - Table Iteration
- Lua - Table Constructors
- Lua - Loop through Table
- Lua - Merge Tables
- Lua - Nested Tables
- Lua - Accessing Table Fields
- Lua - Copy Table by Value
- Lua - Get Entries from Table
- Lua - Table Metatables
- Lua - Tables as Objects
- Lua - Table Inheritance
- Lua - Table Cloning
- Lua - Table Sorting
- Lua - Table Searching
- Lua - Table Serialization
- Lua - Weak Tables
- Lua - Table Memory Management
- Lua - Tables as Stacks
- Lua - Tables as Queues
- Lua - Sparse Tables
- Lua Lists
- Lua - Lists
- Lua - Inserting Elements into Lists
- Lua - Removing Elements from Lists
- Lua - Iterating Over Lists
- Lua - Reverse Iterating Over Lists
- Lua - Accessing List Elements
- Lua - Modifying List Elements
- Lua - List Length
- Lua - Concatenate Lists
- Lua - Slicing Lists
- Lua - Sorting Lists
- Lua - Reversing Lists
- Lua - Searching in Lists
- Lua - Shuffling List
- Lua - Multi-dimensional Lists
- Lua - Sparse Lists
- Lua - Lists as Stacks
- Lua - Lists as Queues
- Lua - Functional Operations on Lists
- Lua - Immutable Lists
- Lua - List Serialization
- Lua - Metatables with Lists
- Lua Modules
- Lua - Modules
- Lua - Returning Functions from Modules
- Lua - Returning Functions Table from Modules
- Lua - Module Scope
- Lua - SubModule
- Lua - Module Caching
- Lua - Custom Module Loaders
- Lua - Namespaces
- Lua - Singleton Modules
- Lua - Sharing State Between Modules
- Lua - Module Versioning
- Lua Metatables
- Lua - Metatables
- Lua - Chaining Metatables
- Lua - Proxy Tables with Metatables
- Lua - Use Cases for Proxy Table
- Lua - Delegation and Tracing via Proxy Tables
- Lua - Metatables vs Metamethods
- Lua - Fallback Mechanisms in Metatables
- Lua - Fallback Cases for Indexing Metamethods
- Lua - Fallback Cases for Arithmetic and Comparison Metamethods
- Lua - Fallback Cases for Other Metamethods
- Lua - Customizing Behavior with Metatables
- Lua - Controlling Table Access
- Lua - Overloading Operators
- Lua - Customizing Comparisons
- Lua - Making a Table Callable
- Lua - Customizing String Representation
- Lua - Controlling Metatable Access
- Lua Coroutines
- Lua - Coroutines
- Lua - Coroutine Lifecycle
- Lua - Communication Between Coroutines
- Lua - Coroutines vs Threads
- Lua - Chaining Coroutines
- Lua - Chaining Coroutines With Scheduler
- Lua - Chaining Coroutines Using Queues
- Lua - Coroutine Control Flow
- Lua - Nested Coroutines
- Lua File Handling
- Lua - File I/O
- Lua - Opening Files
- Lua - Modes for File Access
- Lua - Reading Files
- Lua - Writing Files
- Lua - Closing Files
- Lua - Renaming Files
- Lua - Deleting Files
- Lua - File Buffers and Flushing
- Lua - Reading Files Line by Line
- Lua - Binary File Handling
- Lua - File Positioning
- Lua - Appending to Files
- Lua - Error Handling in File Operations
- Lua - Checking if File exists
- Lua - Checking if File is Readable
- Lua - Checking if File is Writable
- Lua - Checking if File is ReadOnly
- Lua - File Descriptors
- Lua - Creating Temporary Files
- Lua - File Iterators
- Lua - Working with Large Files
- Lua Advanced
- Lua - Error Handling
- Lua - Debugging
- Lua - Garbage Collection
- Lua - Object Oriented
- Lua - Web Programming
- Lua - Database Access
- Lua - Game Programing
- Sorting Algorithms
- Lua - Bubble Sort
- Lua - Insertion Sort
- Lua - Selection Sort
- Lua - Merge Sort
- Lua - Quick Sort
- Searching Algorithms
- Lua - Linear Search
- Lua - Binary Search
- Lua - Jump Search
- Lua - Interpolation Search
- Regular Expression
- Lua - Pattern Matching
- Lua - string.find() method
- Lua - string.gmatch() method
- Lua - string.gsub() method
- Lua Useful Resources
- Lua - Quick Guide
- Lua - Useful Resources
- Lua - Discussion
Lua - Database Access
For simple data operations, we may use files, but, sometimes, these file operations may not be efficient, scalable, and powerful. For this purpose, we may often switch to using databases. LuaSQL is a simple interface from Lua to a number of database management systems. LuaSQL is the library, which provides support for different types of SQL. This include,
SQLite
Mysql
ODBC
In this tutorial, we will be covering database handling of MySQL an SQLite in Lua. This uses a generic interface for both and should be possible to port this implementation to other types of databases as well. First let see how you can do the operations in MySQL.
MySQL db Setup
In order to use the following examples to work as expected, we need the initial db setup. The assumptions are listed below.
You have installed and setup MySQL with default user as root and password as '123456'.
You have created a database test.
You have gone through MySQL tutorial to understand MySQL Basics.
Importing MySQL
We can use a simple require statement to import the sqlite library assuming that your Lua implementation was done correctly.
mysql = require "luasql.mysql"
The variable mysql will provide access to the functions by referring to the main mysql table.
Setting up Connection
We can set up the connection by initiating a MySQL environment and then creating a connection for the environment. It is shown below.
local env = mysql.mysql() local conn = env:connect('test','root','123456')
The above connection will connect to an existing MySQL file and establishes the connection with the newly created file.
Execute Function
There is a simple execute function available with the connection that will help us to do all the db operations from create, insert, delete, update and so on. The syntax is shown below −
conn:execute([[ 'MySQLSTATEMENT' ]])
In the above syntax, we need to ensure that conn is open and existing MySQL connection and replace the 'MySQLSTATEMENT' with the correct statement.
Example - Create Table
A simple create table example is shown below. It creates a table with two parameters id of type integer and name of type varchar.
main.lua
mysql = require "luasql.mysql" local env = mysql.mysql() local conn = env:connect('test','root','123456') print(env,conn) status,errorString = conn:execute([[CREATE TABLE sample2 (id INTEGER, name TEXT);]]) print(status,errorString )
Output
When you run the above program, a table named sample will be created with two columns namely, id and name.
MySQL environment (004BB178) MySQL connection (004BE3C8) 0 nil
In case there is any error, you would be returned an error statement instead of nil. A simple error statement is shown below.
LuaSQL: Error executing query. MySQL: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"id INTEGER, name TEXT)' at line 1
Example - Insert Statement
An insert statement for MySQL is shown below.
conn:execute([[INSERT INTO sample values('11','Raj')]])
Example - Update Statement
An update statement for MySQL is shown below.
conn:execute([[UPDATE sample3 SET name='John' where id ='12']])
Example - Delete Statement
A delete statement for MySQL is shown below.
conn:execute([[DELETE from sample3 where id ='12']])
Example - Select Statement
As far as select statement is concerned, we need to loop through each of the rows and extract the required data. A simple select statement is shown below.
cursor,errorString = conn:execute([[select * from sample]]) row = cursor:fetch ({}, "a") while row do print(string.format("Id: %s, Name: %s", row.id, row.name)) -- reusing the table of results row = cursor:fetch (row, "a") end
In the above code, conn is an open MySQL connection. With the help of the cursor returned by the execute statement, you can loop through the table response and fetch the required select data.
A Complete Example
A complete example including all the above statements is given below.
main.lua
mysql = require "luasql.mysql" local env = mysql.mysql() local conn = env:connect('test','root','123456') print(env,conn) status,errorString = conn:execute([[CREATE TABLE sample3 (id INTEGER, name TEXT)]]) print(status,errorString ) status,errorString = conn:execute([[INSERT INTO sample3 values('12','Raj')]]) print(status,errorString ) cursor,errorString = conn:execute([[select * from sample3]]) print(cursor,errorString) row = cursor:fetch ({}, "a") while row do print(string.format("Id: %s, Name: %s", row.id, row.name)) row = cursor:fetch (row, "a") end -- close everything cursor:close() conn:close() env:close()
Output
When you run the above program, you will get the following output−
MySQL environment (0037B178) MySQL connection (0037EBA8) 0 nil 1 nil MySQL cursor (003778A8) nil Id: 12, Name: Raj
Performing Transactions
Transactions are a mechanism that ensures data consistency. Transactions should have the following four properties −
Atomicity − Either a transaction completes or nothing happens at all.
Consistency − A transaction must start in a consistent state and leave the system in a consistent state.
Isolation − Intermediate results of a transaction are not visible outside the current transaction.
Durability − Once a transaction was committed, the effects are persistent, even after a system failure.
Transaction starts with START TRANSACTION; and ends with commit or rollback statement.
Start Transaction
In order to initiate a transaction, we need to execute the following statement in Lua, assuming conn is an open MySQL connection.
conn:execute([[START TRANSACTION;]])
Rollback Transaction
We need to execute the following statement to rollback changes made after start transaction is executed.
conn:execute([[ROLLBACK;]])
Commit Transaction
We need to execute the following statement to commit changes made after start transaction is executed.
conn:execute([[COMMIT;]])
We have known about MySQL in the above and following section explains about basic SQL operations. Remember transactions, though not explained again for SQLite3 but the same statements should work for SQLite3 as well.
Importing SQLite
We can use a simple require statement to import the SQLite library assuming that your Lua implementation was done correctly. During installation, a folder libsql that contains the database related files.
sqlite3 = require "luasql.sqlite3"
The variable sqlite3 will provide access to the functions by referring to the main sqlite3 table.
Setting Up Connection
We can set up the connection by initiating an SQLite environment and then creating a connection for the environment. It is shown below.
local env = sqlite3.sqlite3() local conn = env:connect('mydb.sqlite')
The above connection will connect to an existing SQLite file or creates a new SQLite file and establishes the connection with the newly created file.
Execute Function
There is a simple execute function available with the connection that will help us to do all the db operations from create, insert, delete, update and so on. The syntax is shown below −
conn:execute([[ 'SQLite3STATEMENT' ]])
In the above syntax we need to ensure that conn is open and existing sqlite3 connection and replace the 'SQLite3STATEMENT' with the correct statement.
Example - Create Table
A simple create table example is shown below. It creates a table with two parameters id of type integer and name of type varchar.
main.lua
sqlite3 = require "luasql.sqlite3" local env = sqlite3.sqlite3() local conn = env:connect('mydb.sqlite') print(env,conn) status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]]) print(status,errorString )
Output
When you run the above program, a table named sample will be created with two columns namely, id and name.
SQLite3 environment (003EC918) SQLite3 connection (00421F08) 0 nil
In case of an error, you would be returned a error statement instead of nil. A simple error statement is shown below.
LuaSQL: unrecognized token: ""'id' INTEGER, 'name' TEXT)"
Example - Insert Statement
An insert statement for SQLite is shown below.
conn:execute([[INSERT INTO sample values('11','Raj')]])
Example - Select Statement
As far as select statement is concerned, we need to loop through each of the rows and extract the required data. A simple select statement is shown below.
cursor,errorString = conn:execute([[select * from sample]]) row = cursor:fetch ({}, "a") while row do print(string.format("Id: %s, Name: %s", row.id, row.name)) -- reusing the table of results row = cursor:fetch (row, "a") end
In the above code, conn is an open sqlite3 connection. With the help of the cursor returned by the execute statement, you can loop through the table response and fetch the required select data.
A Complete Example
A complete example including all the above statements is given below.
main.lua
sqlite3 = require "luasql.sqlite3" local env = sqlite3.sqlite3() local conn = env:connect('mydb.sqlite') print(env,conn) status,errorString = conn:execute([[CREATE TABLE sample ('id' INTEGER, 'name' TEXT)]]) print(status,errorString ) status,errorString = conn:execute([[INSERT INTO sample values('1','Raj')]]) print(status,errorString ) cursor,errorString = conn:execute([[select * from sample]]) print(cursor,errorString) row = cursor:fetch ({}, "a") while row do print(string.format("Id: %s, Name: %s", row.id, row.name)) row = cursor:fetch (row, "a") end -- close everything cursor:close() conn:close() env:close()
Output
When you run the above program, you will get the following output−
SQLite3 environment (005EC918) SQLite3 connection (005E77B0) 0 nil 1 nil SQLite3 cursor (005E9200) nil Id: 1, Name: Raj
We can execute all the available queries with the help of this libsql library. So, please don't stop with these examples. Experiment various query statement available in respective MySQL, SQLite3 and other supported db in Lua.