[Standalone] IcMySQL - Efficient MySQL abstraction

Nice!

5 Likes

nice JOb!

5 Likes

wooow!

4 Likes

NEW MAJOR UPDATE (v3.0.0)

We have redone the whole system to solve major problems and we have taken the opportunity to improve and add support for MySQL, Mongo, Redis and ORM (object relational mapping), apart from all the new features listed in the main post.

The new version can be found uploaded in the repository.
Documentation: Here

6 Likes

Sound cool! I’ll test it

14 Likes

Love the work guys, keep it up!

8 Likes

I swapped from oxmysql to this and now my server runs 5 degrees cooler

10 Likes

Great job, guys! I’m really pleased with what you’re achieving. Thanks for the resources. Let’s keep adding to the forum! :clap::star2:

7 Likes

Thank you very much :ice_cube:

4 Likes

thx :heart:

4 Likes

@Linden will you review v3.0.0 also?

6 Likes

Thank you for taking the time to create this for me and others to use :heart:

6 Likes

I am delighted to hear that you have found the system so useful. Our intention in making it accessible to everyone was precisely that: to offer help and contribute positively to the community.
Your support and kind words mean a lot to us! Please, if you have any problems or suggestions, feel free to share them here. :heart:

7 Likes

No clue what you’re doing to achieve such results.

local curtime = os.nanotime
local results = {}

---@param iterations number
---@param title string | number
---@param func function
local function runBenchmark(iterations, title, func)
    local start = curtime()

    for i = 1, iterations do
        func()
    end

    results[#results + 1] = { (curtime() - start) / iterations, title }
end

---@param iterations number
local function showResults(iterations)
    print(('Average results from %d iterations (ms)'):format(iterations))
    table.sort(results, function(a, b) return a[1] < b[1] end)

    for i = 1, #results do
        local result = results[i]
        print(('#%d - %.4f\t(%s)'):format(i, result[1] / 1e6, result[2]))
    end

    table.wipe(results)
end

---@param n number
---@param tbl table<string, function>
local function benchmark(n, tbl)
    for k, v in pairs(tbl) do
        runBenchmark(n, k, v)
    end

    showResults(n)
end


CreateThread(function()
    local initTable = {
        'DROP TABLE IF EXISTS `test_table`',
        [[CREATE TABLE `test_table` (
        `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
        `username` VARCHAR(50) NOT NULL DEFAULT '0',
        `identifier` VARCHAR(50) NOT NULL DEFAULT '0',
        PRIMARY KEY (`id`)
        )]],
        'TRUNCATE `test_table`',
        'ALTER TABLE `test_table` AUTO_INCREMENT = 1',
    }

    MySQL.transaction.await(initTable)

    local insertUsers = {}

    for i = 1, 5000 do
        insertUsers[i] = { 'INSERT INTO `test_table` (username, identifier) VALUES (?, ?)',
            { 'Testuser_' .. i, 'abcdef' .. i } }
    end

    MySQL.transaction.await(insertUsers)

    local Query = exports.icmysql.AwaitQuery

    benchmark(1000, {
        ['ox'] = function()
            MySQL.query.await('SELECT username FROM test_table WHERE id = ?', { 3 })
        end,
        ['ice'] = function()
            Query(nil, 1, 'SELECT username FROM test_table WHERE id = ?', { 3 })
        end,
    })
end)
[  resources] Started resource test
[script:test] Average results from 1000 iterations (ms)
[script:test] #1 - 0.4476      (ice)
[script:test] #2 - 0.4579      (ox)
     ensure test
[  resources] Stopping resource test
[    c-scripting-core] Creating script environments for test
[  resources] Started resource test
[script:test] Average results from 1000 iterations (ms)
[script:test] #1 - 0.3466      (ox)
[script:test] #2 - 0.4444      (ice)
     ensure test
[  resources] Stopping resource test
[    c-scripting-core] Creating script environments for test
[  resources] Started resource test
[script:test] Average results from 1000 iterations (ms)
[script:test] #1 - 0.3301      (ox)
[script:test] #2 - 0.3763      (ice)
     ensure test
[  resources] Stopping resource test
[    c-scripting-core] Creating script environments for test
[  resources] Started resource test
[script:test] Average results from 1000 iterations (ms)
[script:test] #1 - 0.3547      (ice)
[script:test] #2 - 0.3758      (ox)
3 Likes

I will redo the tests and post the results here.

6 Likes

You’re not even going to achieve anything more than micro-optimisations when both scripts

  • use the same mysql driver
  • use promises
  • use connection pools

The resources don’t run any complex / heavy code by themselves; you instead need to be looking at usability and features… and also compatibility or things like sparse arrays, nil parameters, supported syntax.

2 Likes

I really had done something wrong and the results are basically the same

Average results from 1000 iterations (ms)
#1 - 0.2392      (ox)
#2 - 0.2755      (ice)

Average results from 1000 iterations (ms)
#1 - 0.2537      (ice)
#2 - 0.2989      (ox)

Average results from 1000 iterations (ms)
#1 - 0.2494      (ice)
#2 - 0.3204      (ox)

Average results from 1000 iterations (ms)
#1 - 0.2341      (ox)
#2 - 0.2530      (ice)
7 Likes

I have done an update that improves the performance a lot and exceeds the performance of ox, I have done the benchmark that Linden has provided and here I will show the results that I have obtained after the performance improvement:

With 1.000 Iterations:

With 10.000 Iterations

Note: If someone wants to test the benchmark he/she should remove the provide oxmysql from the icmysql/fxmanifest.lua and set the Config.ReplaceExports option in the icmysql/config.js file to false. This is to avoid problems when starting/restarting the script.

And I’ve added the nil params support for the query values

8 Likes

great progress on this

just wanted to say though,

this file does nothing (most of the time)

as yarn doesnt just check if the file exists, it checks when it was last modified and compares it to the package json’s last modification date

the real way to fix this would be to just not include the package.json & lock files in the released files.
hope this helps :slight_smile: (i had to deal with similar issues in the past lol)

4 Likes

Sorry for my noob question, but is this like a oxmysql replacement?
Seeing some cool features here, just slightly curious upon everything and the rest.
It handling mysql/oxmysql calls? like backwards combatable

4 Likes