8000 GitHub - Srlion/goobie-sql at 1.1
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Srlion/goobie-sql

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Goobie MySQL

A simple and easy-to-use MySQL client for Garry's Mod.

Version Information

The module exposes version constants that you can use to verify or log the library version:

  • goobie_mysql.VERSION: Contains the complete version string.
  • goobie_mysql.MAJOR_VERSION: Contains the major version number.

LuaLS

You can now use LuaLS to get autocomplete and syntax highlighting for the library!

You can find the meta file in luals/goobie_mysql.lua (Don't ask me how to install because I don't know).

Installation

  1. Download the latest version from the GitHub releases.
  2. Extract the module to your Garry's Mod lua/bin directory.

Note: To avoid conflicts when multiple addons use different versions of the library, require the specific version you need:

require("goobie_mysql_1")

---@type goobie_mysql
local goobie_mysql = goobie_mysql_1

When installing the library, ensure you select the version you intend to use.

Previously, it was using SemVer, but I've changed it to use Float-Versioning.

Establishing a Connection

Create a connection object using goobie_mysql.NewConn. You can specify connection options in two ways:

Using a URI

URI Format

The URI format is mysql://[user[:password]@][host][:port]/[database][?properties].

local conn = goobie_mysql.NewConn({
    uri = "mysql://username:password@host:port/database"
})

Using Individual Credentials

local conn = goobie_mysql.NewConn({
    host = "localhost",
    username = "user",
    password = "pass",
    database = "mydb"
})

Additional (optional) settings include:

  • charset (e.g., "utf8mb4")
  • collation (e.g., "utf8mb4_0900_ai_ci")
  • timezone (e.g., "UTC")
  • statement_cache_capacity (e.g., 100)
  • socket (e.g., "/path/to/socket")

Start the connection using either:

Asynchronous Connection

conn:Start(function(err)
    if err then
        print("Connection failed: " .. err.message)
    else
        print("Connected successfully")
    end
end)

Synchronous Connection

conn:StartSync()

Note: StartSync throws an error on failure, so consider using pcall to handle errors.

Connection States

After starting a connection, you can check its state using the following methods:

  • Numeric State: conn:State() Returns a number corresponding to one of the state constants defined in goobie_mysql.STATES.

  • State Name: conn:StateName() Returns a string representation of the current state (e.g., "CONNECTED").

Available states (available via goobie_mysql.STATES):

  • CONNECTED
  • CONNECTING
  • NOT_CONNECTED
  • DISCONNECTED

Additional helper methods:

  • conn:IsConnected()
  • conn:IsConnecting()
  • conn:IsNotConnected()
  • conn:IsDisconnected()

Polling for Connection Events

For asynchronous operations that may not use callbacks directly, you can use the conn:Poll() method to process connection events.

Disconnecting

When you need to close the connection, use one of the following methods:

Asynchronous Disconnection

conn:Disconnect(function(err)
    if err then
        print("Disconnection failed: " .. err.message)
    else
        print("Disconnected successfully")
    end
end)

Synchronous Disconnection

local err = conn:DisconnectSync()
if err then
    print("Disconnection failed: " .. err.message)
else
    print("Disconnected successfully")
end

Error Handling

Most methods return an Error object on failure. This object contains:

  • message: A description of the error.
  • code: A numeric error code.
  • sqlstate (optional): The SQL state string provided by MySQL.

Always check for errors after each operation to handle failures gracefully.

Querying the Database

The module offers methods for running queries, with both asynchronous and synchronous versions.

Run

For queries like INSERT, UPDATE, or DELETE that don’t return data.

Asynchronous

conn:Run("INSERT INTO mytable (column) VALUES (?)", {params = {"value"}}, function(err)
    if err then
        print("Query failed: " .. err.message)
    else
        print("Query executed successfully")
    end
end)

Synchronous

local err = conn:RunSync("INSERT INTO mytable (column) VALUES (?)", {params = {"value"}})
if err then
    print("Query failed: " .. err.message)
else
    print("Query executed successfully")
end

Execute

Like Run, but returns rows_affected and last_insert_id.

Asynchronous

conn:Execute("INSERT INTO mytable (column) VALUES (?)", {params = {"value"}}, function(err, result)
    if err then
        print("Query failed: " .. err.message)
    else
        print("Rows affected: " .. result.rows_affected)
        print("Last insert ID: " .. result.last_insert_id)
    end
end)

Synchronous

local err, result = conn:ExecuteSync("INSERT INTO mytable (column) VALUES (?)", {params = {"value"}})
if err then
    print("Query failed: " .. err.message)
else
    print("Rows affected: " .. result.rows_affected)
    print("Last insert ID: " .. result.last_insert_id)
end

Fetch

Retrieves multiple rows from a SELECT query.

Asynchronous

conn:Fetch("SELECT * FROM mytable WHERE column = ?", {params = {"value"}}, function(err, rows)
    if err then
        print("Query failed: " .. err.message)
    else
        for _, row in ipairs(rows) do
            print(row.column)
        end
    end
end)

Synchronous

local err, rows = conn:FetchSync("SELECT * FROM mytable WHERE column = ?", {params = {"value"}})
if err then
    print("Query failed: " .. err.message)
else
    for _, row in ipairs(rows) do
        print(row.column)
    end
end

FetchOne

Retrieves a single row from a SELECT query.

Asynchronous

conn:FetchOne("SELECT * FROM mytable WHERE id = ?", {params = {1}}, function(err, row)
    if err then
        print("Query failed: " .. err.message)
    elseif row then
        print(row.column)
    else
        print("No row found")
    end
end)

Synchronous

local err, row = conn:FetchOneSync("SELECT * FROM mytable WHERE id = ?", {params = {1}})
if err then
    print("Query failed: " .. err.message)
elseif row then
    print(row.column)
else
    print("No row found")
end

Query Parameters

To prevent SQL injection, always use the params field:

{params = {"value1", "value2"}}

For raw queries (such as multi-statement queries), set raw = true. Use this option with caution and avoid with untrusted input.

Transactions

Group queries into a transaction that can be committed or rolled back.

Asynchronous Transaction

conn:Begin(function(err, txn)
    if err then
        print("Failed to start transaction: " .. err.message)
        return
    end
    local err, rows = txn:Fetch("SELECT * FROM mytable")
    if err then
        print("Query failed: " .. err.message)
        txn:Rollback()
        return
    end
    local err = txn:Commit()
    if err then
        print("Commit failed: " .. err.message)
    end
end)

Synchronous Transaction

conn:BeginSync(function(err, txn)
    if err then
        print("Failed to start transaction: " .. err.message)
        return
    end
    local err = txn:Run("INSERT INTO mytable (column) VALUES ('value')")
    if err then
        txn:Rollback()
        return
    end
    txn:Commit()
end)

Inside a transaction:

  • All query methods (Run, Execute, Fetch, FetchOne) are synchronous and do not take a callback.
  • Check transaction status with txn:IsOpen().
  • Finalize the transaction using txn:Commit() or txn:Rollback().

Ping

Test the connection with a ping (note: it’s not a reliable method to check if the connection is alive).

Asynchronous

conn:Ping(function(err, latency)
    if err then
        print("Ping failed: " .. err.message)
    else
        print("Latency: " .. latency .. "ms")
    end
end)

Synchronous

local err, latency = conn:PingSync()
if err then
    print("Ping failed: " .. err.message)
else
    print("Latency: " .. latency .. "ms")
end

Examples

Simple Query

local goobie_mysql = require("goobie_mysql")

local conn = goobie_mysql.NewConn({
    host = "localhost",
    username = "user",
    password = "pass",
    database = "mydb"
})

conn:StartSync()

local err, rows = conn:FetchSync("SELECT * FROM mytable")
if err then
    print("Query failed: " .. err.message)
else
    for _, row in ipairs(rows) do
        print(row.column)
    end
end

Transaction Example

local goobie_mysql = require("goobie_mysql")

local conn = goobie_mysql.NewConn({
    host = "localhost",
    username = "user",
    password = "pass",
    database = "mydb"
})

conn:StartSync()

conn:BeginSync(function(err, txn)
    if err then
        print("Failed to start transaction: " .. err.message)
        return
    end
    local err = txn:Run("INSERT INTO mytable (column) VALUES ('value1')")
    if err then
        print("Insert failed: " .. err.message)
        txn:Rollback()
        return
    end
    local err = txn:Run("INSERT INTO mytable (column) VALUES ('value2')")
    if err then
        print("Insert failed: " .. err.message)
        txn:Rollback()
        return
    end
    local err = txn:Commit()
    if err then
        print("Commit failed: " .. err.message)
    end
end)
0