1. Post #121
    syl0r's Avatar
    January 2012
    428 Posts
    I'd guess this is because Lua's C errors are going to jump straight past the destructor of any C++ object. That'd mean the lock guard here never unlocks.

    It's annoying and also means there's probably many other bugs in the module, but that's how Lua's C API works.
    Yup, that's what's causing it. Unfortunately that is what you will get when you are mixing two languages that have vastly different language constructs (and both of which suck).
    I was aware of the RAII issue with LUA and I did go through most of the code to find any issues, but I somehow missed that one. The sad thing is that some scenarios (such as stack overflow or out of memory) a crash is unavoidable. Even without RAII, a longjump will always fuck up your code.

    As a sidenote, there's only very few scenarios where you should use db:escape(). A prepared query (if possible) should always be preferred.

  2. Post #122
    BlackCetha's Avatar
    June 2014
    9 Posts
    I am currently running into issues. It seems to me like the callback just doesnt fire.

    This is how my function works:
    Code:
    local queryDoesExist = db:prepare( [[
      SELECT id FROM items
      WHERE name = ?
    ]] )
    
    function doesExist ( name, callback )
      print "0"
    
      queryDoesExist:setString( 1, name )
    
      function queryDoesExist:onSuccess ( rows )
        print "1"
    
        return callback( #rows ~= 0 )
      end
    
      function queryDoesExist:onError ( err )
        print( "Error: " .. err )
      end
    
      print "2"
    
      queryDoesExist:start()
    end
    In this example, it works if it is instantly run after the database connected.
    Calling it with lua_run or a proxy function doesn't work. It would print "0" and "2".

  3. Post #123

    August 2014
    365 Posts
    I am currently running into issues. It seems to me like the callback just doesnt fire.

    This is how my function works:

    In this example, it works if it is instantly run after the database connected.
    Calling it with lua_run or a proxy function doesn't work. It would print "0" and "2".
    I just tested your code and it works fine for me.

    I suggest you clean it up a little bit though.

    Code:
    function doesExist(name, callback)
    	local q = [[SELECT id FROM items WHERE name = ?;]]
    	local query = db:prepare(q)
    
    	query:setString(1, name)
    
    	function query:onError(err)
    		print("Error "..err)
    	end
    	function query:onSuccess(data)
    		callback(data[1] and true or false)
    	end
    
    	query:start()
    end

  4. Post #124
    BlackCetha's Avatar
    June 2014
    9 Posts
    I suggest you clean it up a little bit though.
    I'm not going to argue about coding style.

    The weird thing is that it is just this specific function signature
    Code:
    function ( ..., callback )
    that doesn't seem to work. Every other function I've written seems to work fine.

    After some testing it does work everytime once I :wait() for the query to finish.
    I rewrote the function and query from scratch, and it still doesn't work even if I
    put a syncronous function in the :onSuccess handler.

    Here's my current code:
    Code:
    queries = {
      ...,
      groupExists = [[
        SELECT
          group_id
        FROM
          groups
        WHERE
          name = ?
      ]],
      ...
    }
    
    ucl.groupExists = function ( name, callback )
      ULib.checkArg( 1, "ULib.ucl.addGroup", "string", name )
    
      local groupExists = db:prepare( queries.groupExists )
    
      groupExists:setString( 1, name )
    
      function groupExists:onSuccess ( rows )
        callback( #rows == 1 )
      end
    
      function groupExists:onError ( errstring )
        db.LogError( "ULib.ucl.groupExists", name, errstring )
      end
    
      groupExists:start()
      groupExists:wait( true )
    end
    I really want to get rid of the :wait() though.
    Maybe there's some LUA-specific mistake in here that I don't have the knowledge to see,
    after all I'm coming from JS/Node where something like this style works fine.

  5. Post #125
    bigdogmat's Avatar
    May 2014
    800 Posts
    I'm not going to argue about coding style.

    The weird thing is that it is just this specific function signature

    that doesn't seem to work. Every other function I've written seems to work fine.

    After some testing it does work everytime once I :wait() for the query to finish.
    I rewrote the function and query from scratch, and it still doesn't work even if I
    put a syncronous function in the :onSuccess handler.

    Here's my current code:



    I really want to get rid of the :wait() though.
    Maybe there's some LUA-specific mistake in here that I don't have the knowledge to see,
    after all I'm coming from JS/Node where something like this style works fine.
    That function looks fine, the only reason I could see it needing wait would if be if you've made the callback synchronous. If you could post your whatever your callback function is.

    Code:
    print(1)
    local t = db:prepare "SELECT 5 + ?"
    
    function kkkk()
      print(2)
    
      t:setNumber(1, 5)
    
      function t:onSuccess(tab)
        print("Success:", 3)
        PrintTable(tab)
      end
    
      function t:onError(err)
        print("Error:", 3)
        print(err)
      end
    
      t:start()
    end
    Also if you could, run the code above anytime after you've run db:connect(), then call the kkkk() function through something such as lua_run. Just to make sure this is user mistake and not an issue on your installation.

  6. Post #126
    BlackCetha's Avatar
    June 2014
    9 Posts
    It seems like it doesnt even get to the :onSuccess handler.

    Output from your debug code:
    Code:
    [DB] Connected
    1
    2
    Success: 3
    1:
        5 + ?    =    10
    
    
    lua_run kkkk()
    > kkkk() ...
    2
    The first bit where it works is called directly from the script file.

    If it makes any difference I'm running MariaDB on a Ubuntu Server 16.04 VM together with srcds.

  7. Post #127
    syl0r's Avatar
    January 2012
    428 Posts
    It seems like it doesnt even get to the :onSuccess handler.

    Output from your debug code

    The first bit where it works is called directly from the script file.

    If it makes any difference I'm running MariaDB on a Ubuntu Server 16.04 VM together with srcds.
    For me it prints
    lua_run kkkk()
    > kkkk()...
    2
    Success:        3
    1:
                    5 + ?   =       10
    
    regardless of whether or not I call it from a script or lua_run.
    MariaDB should not make any difference since it is mostly compatible with mysql.

  8. Post #128
    BlackCetha's Avatar
    June 2014
    9 Posts
    Here is the relevant code If you don't mind reading through it:
    https://gist.github.com/BlackCetha/f...6bd9684f53a573

    It has some design flaws, but the only thing I can't fix myself is the queries.

  9. Post #129
    syl0r's Avatar
    January 2012
    428 Posts
    I ran your code with some dummy db entries and it printed:
    [DB] Connecting
    Connected to database as server #1 'fagsad'
    
    So I think that works on my end too.

  10. Post #130
    bigdogmat's Avatar
    May 2014
    800 Posts
    Here is the relevant code If you don't mind reading through it:
    https://gist.github.com/BlackCetha/f...6bd9684f53a573

    It has some design flaws, but the only thing I can't fix myself is the queries.
    Just to make sure, you have downloaded the latest release from this page right?

  11. Post #131
    BlackCetha's Avatar
    June 2014
    9 Posts
    Yes, I'm running the latest version.
    MariaDB, libmysql and the srcds itself should also be the latest versions.
    There are no addons installed on the server except my script that I published, ULib and ULX.

    Code:
    print(mysqloo.VERSION)
    9
    
    print(mysqloo.MINOR_VERSION)
    3

  12. Post #132
    BlackCetha's Avatar
    June 2014
    9 Posts
    After some testing it seems like my installation is broken. I'll just wipe the VM and try again.

    Thanks for helping.

  13. Post #133
    Gold Member

    March 2012
    2,309 Posts
    Heads up: MySQLOO seems to cause a crash when used after a changelevel on the dev branch.

    Tested using DarkRP with Windows SRCDS.

    It could be a regression with the changes made to binary modules.

    (You'll need to add a bot or join the server or something to kick the server out of hibernation before changing level to trigger the crash.)

  14. Post #134
    Willox said I can put anything in here, so I've put
    *meow*
    Willox's Avatar
    December 2009
    2,954 Posts
    Heads up: MySQLOO seems to cause a crash when used after a changelevel on the dev branch.

    Tested using DarkRP with Windows SRCDS.

    It could be a regression with the changes made to binary modules.

    (You'll need to add a bot or join the server or something to kick the server out of hibernation before changing level to trigger the crash.)
    no dump?

  15. Post #135
    Gold Member

    March 2012
    2,309 Posts

  16. Post #136
    Willox said I can put anything in here, so I've put
    *meow*
    Willox's Avatar
    December 2009
    2,954 Posts
    It looks like a normal C function call is failing from a query callback which calls in to http.Fetch or HTTP. Sounds stupid, but could you verify the server's content before trying again?

  17. Post #137
    Gold Member

    March 2012
    2,309 Posts
    It looks like a normal C function call is failing from a query callback which calls in to http.Fetch or HTTP. Sounds stupid, but could you verify the server's content before trying again?
    Seems to happen if sv_lan is changed.

    i.e.
    [sv_lan 0 is set by default]
    1. Startup server
    2. Run http.Fetch
    3. sv_lan 1
    4. changelevel
    5. Run http.Fetch again
    6. Crash

    The same also happens in reverse (1 -> 0).

    The reason for the change in sv_lan was because I had it in server.cfg and not autoexec.cfg. Setting sv_lan in server.cfg does not work until changelevel.

  18. Post #138
    Willox said I can put anything in here, so I've put
    *meow*
    Willox's Avatar
    December 2009
    2,954 Posts
    Seems to happen if sv_lan is changed.

    i.e.
    [sv_lan 0 is set by default]
    1. Startup server
    2. Run http.Fetch
    3. sv_lan 1
    4. changelevel
    5. Run http.Fetch again
    6. Crash

    The same also happens in reverse (1 -> 0).

    The reason for the change in sv_lan was because I had it in server.cfg and not autoexec.cfg. Setting sv_lan in server.cfg does not work until changelevel.
    So this issue is specific to HTTP and not MySQLoo or any 3rd party binary module stuff?

  19. Post #139
    Gold Member

    March 2012
    2,309 Posts
    So this issue is specific to HTTP and not MySQLoo or any 3rd party binary module stuff?
    Yeah, I didn't initially look into the root cause and just saw that it happened when MySQLOO was installed, which is why I reported it here. It seems to affect all uses of HTTP, which MySQLOO happens to use for its update checks.

    That said, it's still a regression in GMod (it doesn't happen on the main branch) but I'll report it over on garrysmod-issues if you want.

  20. Post #140
    Don't PM me about moderation - PM any of the mods.
    Robotboy655's Avatar
    May 2008
    15,497 Posts
    Yeah, I didn't initially look into the root cause and just saw that it happened when MySQLOO was installed, which is why I reported it here. It seems to affect all uses of HTTP, which MySQLOO happens to use for its update checks.

    That said, it's still a regression in GMod (it doesn't happen on the main branch) but I'll report it over on garrysmod-issues if you want.
    Looking into it atm

    Edit: Should be fixed in Dev and Pre-Release, sorry about that
    Reply With Quote Edit / Delete Reply Windows 10 Chrome Estonia Show Events Friendly Friendly x 2 (list)

  21. Post #141
    bigdogmat's Avatar
    May 2014
    800 Posts
    Code:
    local co = coroutine.create(function()
      --local q = database:query "SELECT 5 + 5"
      --q:start()
    end)
    
    coroutine.resume(co)
    I'm not sure if this has anything to do with the module, but for whatever reason uncommenting the above 2 lines cause the `coroutine.resume` call to error with

    bad argument #1 to 'resume' (table expected, got thread)
    Edited:

    I've heard coroutines have issues with modules, so I'm assuming that's the case here.
    Reply With Quote Edit / Delete Reply Windows 10 Chrome United States Show Events Agree Agree x 1 (list)

  22. Post #142
    bigdogmat's Avatar
    May 2014
    800 Posts
    Last update added ILuaBase->SetState, so coroutine issue can be fixed. Base module changes here

  23. Post #143
    syl0r's Avatar
    January 2012
    428 Posts
    I don't see how I am supposed to use that function to solve the coroutine issue. I really don't want to save the lua_state in a variable since that seems incredibly bad to me.

  24. Post #144
    bigdogmat's Avatar
    May 2014
    800 Posts
    As far as I understood, the reason it didn't work was because the ILuaBase was using the wrong Lua state. Last update added ILuaBase->SetState which allowed the state to be corrected as seen in the LUA_FUNCTION define.

  25. Post #145
    syl0r's Avatar
    January 2012
    428 Posts
    As far as I understood, the reason it didn't work was because the ILuaBase was using the wrong Lua state. Last update added ILuaBase->SetState which allowed the state to be corrected as seen in the LUA_FUNCTION define.
    The LUA_FUNCTION macro seems to not work with static class functions. Unfortunately pretty much all of the lua functions in my module are static class functions, so I can't use the macro without having to rewrite a lot of code.
    I refuse to restructure my code just because the macro was only intended for C style programming (even though it's for C++....).
    I might come up with a better (own) solution at some point, but I don't see it as a high priority right now.

  26. Post #146
    Bings's Avatar
    June 2014
    263 Posts
    Im fresh outta the box when it comes to MYSQLOO (I know basic SQL though im not that hopeless ) but im trying to make a prepared query but ive ran into a problem with dates

    Far as I can tell setDate doesn't exist and can't find an easy alternative - wondering if anyone knows what I can do as an alternative? or is there nothing that can be done?

    Example of what on earth im on about

    Code:
    local preparedQuery = db:prepare("INSERT INTO table (`date`) VALUES(?)")
    
    preparedQuery:setDate(1, '2017-04-27') -- (not sure if how ive formatted the date - but it doesn't get that far anyway)
    preparedQuery:start()
    And the error just in case you want a peaky
    Code:
    [ERROR] addons/folder/lua/autorun/server/sql.lua:46: attempt to call method 'setDate' (a nil value)
      1. unknown - addons/folder/lua/autorun/server/sql.lua:46

  27. Post #147
    bigdogmat's Avatar
    May 2014
    800 Posts
    Do

    Code:
    preparedQuery:setString(1, "2017-04-27")
    Reply With Quote Edit / Delete Reply Windows 10 Chrome United States Show Events Friendly Friendly x 1 (list)

  28. Post #148
    Bings's Avatar
    June 2014
    263 Posts
    Do

    Code:
    preparedQuery:setString(1, "2017-04-27")
    Thanks for that :)

  29. Post #149
    bigdogmat's Avatar
    May 2014
    800 Posts
    Seems making a query wait inside the `onConnected` callback causes the `onConnected` callback itself to be called. If the code below is used you'll see it print out 1 continually.

    Code:
    function database:onConnected()
      print(1)
    
      local query = database:query "SELECT 5"
      query:start()
      query:wait()
    end

  30. Post #150
    syl0r's Avatar
    January 2012
    428 Posts
    Seems making a query wait inside the `onConnected` callback causes the `onConnected` callback itself to be called. If the code below is used you'll see it print out 1 continually.

    Code:
    function database:onConnected()
      print(1)
    
      local query = database:query "SELECT 5"
      query:start()
      query:wait()
    end
    Yeah I found the cause. Thanks for pointing that out.
    I will release a fixed version soonish.