1. Post #121
    syl0r's Avatar
    January 2012
    430 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
    839 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
    430 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
    430 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
    839 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,310 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,967 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,310 Posts

  16. Post #136
    Willox said I can put anything in here, so I've put
    *meow*
    Willox's Avatar
    December 2009
    2,967 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,310 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,967 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,310 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,694 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
    839 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
    839 Posts
    Last update added ILuaBase->SetState, so coroutine issue can be fixed. Base module changes here

  23. Post #143
    syl0r's Avatar
    January 2012
    430 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
    839 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
    430 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
    839 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
    839 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
    430 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.

  31. Post #151
    Fillipuster's Avatar
    August 2014
    404 Posts
    Sorry if I missed something obvious here, I'm not SQL expert what so ever, but.

    I have a function that'll run a certain query. However, before that, it calls another function which also runs a query, to check some data. The second function returns either true or false depending on the result.

    The problem is, when I run the main function, it seems to call the second function, but then continue on it's wait, not "waiting" from a return value from the second function.

    How would I work around this? Can I not use separate functions that call queries and have then wait for each other to finish? Or do I have to make a huge stack of queries inside callback functions?

    -FP

  32. Post #152
    Luni's Avatar
    July 2012
    1,382 Posts
    Sorry if I missed something obvious here, I'm not SQL expert what so ever, but.

    I have a function that'll run a certain query. However, before that, it calls another function which also runs a query, to check some data. The second function returns either true or false depending on the result.

    The problem is, when I run the main function, it seems to call the second function, but then continue on it's wait, not "waiting" from a return value from the second function.

    How would I work around this? Can I not use separate functions that call queries and have then wait for each other to finish? Or do I have to make a huge stack of queries inside callback functions?

    -FP
    You can use coroutines for that -- I don't too often, but it's nice when you need to do a bunch of queries in a row and don't want nested callback hell. If you have a generic "run SQL query" function you can throw in something like this:
    local cr = coroutine.running()
    if cr then
    	function query:onSuccess()
    		local ok, res = coroutine.resume(cr, self:GetData())
    		if not ok then
    			error(debug.traceback(cr, res))
    		end
    	end
    	query:start()
    	return coroutine.yield()
    end
    

  33. Post #153

    April 2017
    39 Posts
    Hi I seem to be having an issue with your module,

    I seem to be receiving an error stating


    But this is really confusing me because the database this is connected to is here, and I can literally see both of the tables inside of the database;


    If I've made a retarded mistake, which I have a tendency to make, please inform me.

    Thanks,


    -Tom

  34. Post #154
    syl0r's Avatar
    January 2012
    430 Posts
    That error indicates that you are connected to the wrong database. One where the player table does not exist.

  35. Post #155
    Known to all as "ARitz Cracker"
    LegoGuy's Avatar
    March 2009
    2,436 Posts
    Henlo pls accept

    Already tested this out and it works
    Reply With Quote Edit / Delete Reply Windows 10 Waterfox Canada Show Events Winner Winner x 1 (list)

  36. Post #156
    Blue's Clues's Avatar
    October 2016
    3 Posts
    Its funny how so many things still are so outdated that could be good but require tmysql4
    Reply With Quote Edit / Delete Reply Windows 10 Chrome United States Show Events Disagree Disagree x 3 (list)

  37. Post #157
    Known to all as "ARitz Cracker"
    LegoGuy's Avatar
    March 2009
    2,436 Posts
    Its funny how so many things still are so outdated that could be good but require tmysql4
    You could always use the wrapper .-.
    Reply With Quote Edit / Delete Reply Windows 10 Waterfox Canada Show Events Agree Agree x 2 (list)

  38. Post #158
    Jompe's Avatar
    September 2015
    57 Posts
    I got a question about MySQL. Please check my thread if you know how I would return in a function using MySQL. Further explained in the thread.

    https://facepunch.com/showthread.php?t=1574923