• gmsv_mysqloo - Updated OO MySQL Module (multiple statements/stored procs!)
    139 replies, posted
[QUOTE=Unknown Gamer;48900952]I think people still use MySQLOO is because MySQLOO is really the only compatible module with most MySQL addons. I'm no expert at modules or MySQL so correct me if im wrong :P[/QUOTE] Then convert them; almost all of the functions have similar usage.
[QUOTE=code_gs;48901176]Then convert them; almost all of the functions have similar usage.[/QUOTE] Would you give a list of what to change from. It'd be helpful for the people who want to convert. Like this. Ex: MySQLOO function DB:Connect tmysqloo function DB:Query (Know that im horrible at MySQL)
Fuck it, I'm making a wrapper for tmysql so you could just drop it in as a replacement for mysqloo.
[QUOTE=BlackAwps;48901946]Fuck it, I'm making a wrapper for tmysql so you could just drop it in as a replacement for mysqloo.[/QUOTE] How about adding a callback for when it is connected as well? That's the only thing missing that's stopped me from switching pointshop over, I've got everything else on tmysql4 already.
Don't worry, I have that covered. [lua]-- TO INSTALL: SAVE AS lua/includes/modules/mysqloo.lua and have tmysql4 install in lua/bin require("tmysql4") mysqloo = { VERSION = "8.2 tmysql4", MYSQL_VERSION = MYSQL_VERSION, MYSQL_INFO = MYSQL_INFO, DATABASE_CONNECTED = 0, DATABASE_CONNECTING = 1, DATABASE_NOT_CONNECTED = 2, DATABASE_INTERNAL_ERROR = 3, QUERY_NOT_RUNNING = 0, QUERY_RUNNING = 1, QUERY_READING_DATA = 2, QUERY_COMPLETE = 3, QUERY_ABORTED = 4, OPTION_NUMERIC_FIELDS = 1, OPTION_NAMED_FIELDS = 2, OPTION_INTERPRET_DATA = 4, OPTION_CACHE = 8, CLIENT_MULTI_STATEMENTS = CLIENT_MULTI_STATEMENTS, CLIENT_MULTI_RESULTS = CLIENT_MULTI_RESULTS, CLIENT_INTERACTIVE = CLIENT_INTERACTIVE, } local gofuckurself = {} gofuckurself.__index = gofuckurself local seriouslyeatadick = {} seriouslyeatadick.__index = seriouslyeatadick function mysqloo.connect(host, username, password, database, port, sockt, flags) return setmetatable({ host = host, username = username, password = password, database = database, port = port, socket = socket, flags = flags, connected = false, },gofuckurself) end function gofuckurself:connect() self.db, err = tmysql.initialize(self.host, self.username, self.password, self.database, self.port, self.socket, self.flags) if not self.db then self:onConnectionFailed(err) return end self.connected = true self:onConnected() end function gofuckurself:onConnected() -- Blank function that gets overwritten end function gofuckurself:onConnectionFailed(err) -- Blank function that gets overwritten end function gofuckurself:query(query) return setmetatable({ db = self.db, query = query, running = false, complete = false, error = "", lastid = 0, affected = 0, data = {}, abort = false, option = mysqloo.OPTION_NAMED_FIELDS, },seriouslyeatadick) end function gofuckurself:setCharset(str) self.db:SetCharacterSet(str) -- Look at me, adding fuctionality to mysqloo WHAT A NICE GUY I AM end function gofuckurself:escape(str) return self.db:Escape(str) end function gofuckurself:abortAllQueries() -- rofl go fuck urself end function gofuckurself:status() if self.connected then return mysqloo.DATABASE_CONNECTED else return mysqloo.DATABASE_NOT_CONNECTED end -- ya fuk u im not supporting the other bullshit end function gofuckurself:wait() -- ya seriously, if you think im going to support this you can FUCK RIGHT OFF end function gofuckurself:serverVersion() return 1234 -- Who cares end function gofuckurself:serverInfo() return MYSQL_VERSION -- Who cares end function gofuckurself:hostInfo() return MYSQL_INFO -- Who cares end function seriouslyeatadick:start() self.running = true self.db:Query(self.query, function(results) if self.abort then return end -- yeah, deal with it self.doingdata = true results = results[1] -- xd skip all other data sets BECAUSE WHY NOT self.error = results.error self.lastid = results.lastid self.affected = results.affected self.data = results.data if results.status then self:onSuccess(self.data) for k,v in pairs(self.data) do self:onData({k=v}) -- ??? end else self:onError(self.error, self.query) end self.doingdata = false self.complete = true end, nil, (self.option == mysqloo.OPTION_NUMERIC_FIELDS)) end function seriouslyeatadick:onSuccess(data) -- Blank function that gets overwritten end function seriouslyeatadick:onData(data) -- Blank function that gets overwritten end function seriouslyeatadick:onError(err) -- Blank function that gets overwritten end function seriouslyeatadick:isRunning() return self.running end function seriouslyeatadick:getData() return self.data end function seriouslyeatadick:abort() self.abort = true end function seriouslyeatadick:lastInsert() return self.lastid end function seriouslyeatadick:affectedRows() return self.affected end function seriouslyeatadick:status() -- OH BOY if self.doingdata then return mysqloo.QUERY_READING_DATA elseif self.abort then return mysqloo.QUERY_ABORTED elseif self.complete then return mysqloo.QUERY_COMPLETE elseif self.running then return mysqloo.QUERY_RUNNING else return mysqloo.QUERY_NOT_RUNNING end end function seriouslyeatadick:setOption(option) self.option = option end function seriouslyeatadick:wait() -- Yeah no end function seriouslyeatadick:error() return self.error end[/lua] [del]It's going to need an updated tmysql4, so until I make a new build the mysqloo.OPTION_NUMERIC_FIELDS won't work just yet.[/del] Updated tmysql4 to support results with numbers as keys instead of field-named strings.
Would you guys say that tmysql4 is vastly superior to mysqloo? I have yet to really see any speed tests to determine which module is faster.
[QUOTE=Jocken300;48903328]Would you guys say that tmysql4 is vastly superior to mysqloo? I have yet to really see any speed tests to determine which module is faster.[/QUOTE] Absolutely. tmysql has much better garbage collection and isn't plagued with memory leaks from simply sending in queries or aborting a connection. It also, as recently mentioned, allows setting column/database charset.
i am reentering the gmod scene. MYSQLOO SUCKS OH GOD WHY DO PEOPLE USE IT *distant wailing* i am now leaving the gmod scene again.
[QUOTE=BlackAwps;48902069]Don't worry, I have that covered. [lua]function gofuckurself:connect() self.db, err = tmysql.initialize(self.host, self.username, self.password, self.database, self.port, self.socket, self.flags) if not self.db then self.onConnectionFailed(self,err) return end self.connected = true self.onConnected(self) end[/lua] [editline]14th October 2015[/editline] Anyone mind testing this for me? [lua]require("tmysql4") mysqloo = { VERSION = "8.2 tmysql4", MYSQL_VERSION = MYSQL_VERSION, MYSQL_INFO = MYSQL_INFO, DATABASE_CONNECTED = 0, DATABASE_CONNECTING = 1, DATABASE_NOT_CONNECTED = 2, DATABASE_INTERNAL_ERROR = 3, QUERY_NOT_RUNNING = 0, QUERY_RUNNING = 1, QUERY_READING_DATA = 2, QUERY_COMPLETE = 3, QUERY_ABORTED = 4, OPTION_NUMERIC_FIELDS = 1, OPTION_NAMED_FIELDS = 2, OPTION_INTERPRET_DATA = 4, OPTION_CACHE = 8, CLIENT_MULTI_STATEMENTS = CLIENT_MULTI_STATEMENTS, CLIENT_MULTI_RESULTS = CLIENT_MULTI_RESULTS, CLIENT_INTERACTIVE = CLIENT_INTERACTIVE, } local gofuckurself = {} gofuckurself.__index = gofuckurself local seriouslyeatadick = {} seriouslyeatadick.__index = seriouslyeatadick function mysqloo.connect(host, username, password, database, port, sockt, flags) return setmetatable({ host = host, username = username, password = password, database = database, port = port, socket = socket, flags = flags, connected = false, },gofuckurself) end function gofuckurself:connect() self.db, err = tmysql.initialize(self.host, self.username, self.password, self.database, self.port, self.socket, self.flags) if not self.db then self:onConnectionFailed(err) return end self.connected = true self:onConnected() end function gofuckurself:onConnected() -- Blank function that gets overwritten end function gofuckurself:onConnectionFailed(err) -- Blank function that gets overwritten end function gofuckurself:query(query) return setmetatable({ db = self.db, query = query, running = false, complete = false, error = "", lastid = 0, affected = 0, data = {}, option = mysqloo.OPTION_NUMERIC_FIELDS, },seriouslyeatadick) end function gofuckurself:escape(str) return self.db:Escape(str) end function gofuckurself:abortAllQueries() -- rofl go fuck urself end function gofuckurself:status() if self.connected then return mysqloo.DATABASE_CONNECTED else return mysqloo.DATABASE_NOT_CONNECTED end -- ya fuk u im not supporting the other bullshit end function gofuckurself:wait() -- ya seriously, if you think im going to support this you can FUCK RIGHT OFF end function gofuckurself:serverVersion() return 1234 -- Who cares end function gofuckurself:serverInfo() return MYSQL_VERSION -- Who cares end function gofuckurself:hostInfo() return MYSQL_INFO -- Who cares end function seriouslyeatadick:start() self.running = true self.db:Query(self.query, function(results) if self.abort then return end -- yeah, deal with it self.doingdata = true results = results[1] -- xd skip all other data sets BECAUSE WHY NOT self.error = results.error self.lastid = results.lastid self.affected = results.affected self.data = results.data if results.status then self:onSuccess(self.data) for k,v in pairs(self.data) do self:onData({k=v}) -- ??? end else self:onError(self.error, self.query) end self.doingdata = false self.complete = true end, nil, (self.option == mysqloo.OPTION_NUMERIC_FIELDS)) end function seriouslyeatadick:onSuceess(data) -- Blank function that gets overwritten end function seriouslyeatadick:onData(data) -- Blank function that gets overwritten end function seriouslyeatadick:onError(err) -- Blank function that gets overwritten end function seriouslyeatadick:isRunning() return self.running end function seriouslyeatadick:getData() return self.data end function seriouslyeatadick:abort() self.abort = true end function seriouslyeatadick:lastInsert() return self.lastid end function seriouslyeatadick:affectedRows() return self.affected end function seriouslyeatadick:status() -- OH BOY if self.doingdata then return mysqloo.QUERY_READING_DATA elseif self.abort then return mysqloo.QUERY_ABORTED elseif self.complete then return mysqloo.QUERY_COMPLETE elseif self.running then return mysqloo.QUERY_RUNNING else return mysqloo.QUERY_NOT_RUNNING end end function seriouslyeatadick:setOption(option) self.option = option end function seriouslyeatadick:wait() -- Yeah no end function seriouslyeatadick:error() return self.error end[/lua] It's going to need an updated tmysql4, so until I make a new build the mysqloo.OPTION_NUMERIC_FIELDS won't work just yet.[/QUOTE] I don't mind testing this. Where do I put this? lua/autorun?
[QUOTE=Unknown Gamer;48907956]I don't mind testing this. Where do I put this? lua/autorun?[/QUOTE] lua/autorun/server; serverside module.
well for one you're not escaping your strings, which is a massive security issue, but mysql also doesn't properly store unicode because mysql is terrible. Use a blob or something similar.
[QUOTE=Map in a box;48910349]well for one you're not escaping your strings, which is a massive security issue, but mysql also doesn't properly store unicode because mysql is terrible. Use a blob or something similar.[/QUOTE] Use the utf8mb4 'char set'
[QUOTE=code_gs;48907983]lua/autorun/server; serverside module.[/QUOTE] You would actually want to put this in lua/includes/modules so require("mysqloo") would work as normal and you wouldn't have to touch a single line of any addon that uses it.
On popular request I have made a benchmark for both modules. Here are the results. times are in seconds. mysqloo: [CODE]Querys 25000 Average 0.00087432357579928 Minimum 0.00033150375963942 Maximum 0.0095045841553656[/CODE] tmysql4: [CODE]Querys 25000 Average 0.00022150328762435 Minimum 0.00004837978 Maximum 0.018824848131715[/CODE] Conclusion: tmysql4 average time is 0.000652820288 lower than that of mysqloo. tmysql4 minimum time is 0.00028312397 lower than that of mysqloo. tmysql4 maximum time is 0.00932026397 higher than that of mysqloo. The lua I used: tmysql4: [CODE]require("tmysql4") local db = tmysql.initialize( "127.0.0.1", "root", "root", "test", 3306, nil, CLIENT_MULTI_RESULTS ) local tab = {} timer.Create( "AverageSqlQuery", 10, 0, function() local min, avg, max = 1, 0, 0 for i = 1, #tab do local num = tab[ i ] avg = avg + num if min > num then min = num elseif max < num then max = num end end print("\n") print("Querys", #tab) print( "Average", avg / #tab ) print( "Minimum", min ) print( "Maximum", max ) end ) hook.Add( "Think", "mysqlBenchmark", function() local docheck = true local t = SysTime() db:Query( "select * from table", function( result ) if result[ 1 ].status ~= true then docheck = false table.insert( tab, SysTime() - t ) return end end ) while docheck do db:Poll() end end )[/CODE] mysqloo: [CODE]require("mysqloo") local db = mysqloo.connect( "127.0.0.1", "root", "root", "test", 3306 ) function db:onConnected() print( "Database has connected!" ) end db:connect() local tab = {} timer.Create( "AverageSqlQuery", 10, 0, function() local min, avg, max = 1, 0, 0 for i = 1, #tab do local num = tab[ i ] avg = avg + num if min > num then min = num elseif max < num then max = num end end print("\n") print("Querys", #tab) print( "Average", avg / #tab ) print( "Minimum", min ) print( "Maximum", max ) end ) hook.Add( "Think", "mysqlBenchmark", function() local t = SysTime() local q = db:query( "select * from `table`;" ) function q:onSuccess( data ) table.insert( tab, SysTime() - t ) return end q:start() q:wait() end )[/CODE] The table table had 1 row. Results may vary between connection speeds, cpu speeds etc. And yes. If I had optimized my lua a bit more tmysql4 results would have been even lower. Another note: mysqloo is anoying and did not accept the same query as tmysql4 did. [CODE]tmysql4 allowed "select * from table" mysqloo did not. I had to change it to "select * from `table`;"[/CODE]
[QUOTE=darkjacky;48922624] [CODE] while docheck do db:Poll() end [/CODE] [/QUOTE] You're a genius. I can use that to implement wait() into my mysqloo wrapper!
[QUOTE=BlackAwps;48923380]You're a genius. I can use that to implement wait() into my mysqloo wrapper![/QUOTE] Please don't. If you can't connect to the server this will hang forever. +its horrible.
Can you make it support non-ascii chars?
What is the alternative for sql.Begin() and sql.Commit() in here?
[QUOTE=Pwned231;50763918]What is the alternative for sql.Begin() and sql.Commit() in here?[/QUOTE] Read the wiki page for the functions and they give you a hint: [url]https://wiki.garrysmod.com/page/sql/Commit[/url] [url]https://wiki.garrysmod.com/page/sql/Begin[/url] If you are still not sure: They are a quick way to run BEGIN and COMMIT SQL Key works [url]http://dev.mysql.com/doc/refman/5.7/en/begin-end.html[/url]
[QUOTE=andreblue;50764990]Read the wiki page for the functions and they give you a hint: [url]https://wiki.garrysmod.com/page/sql/Commit[/url] [url]https://wiki.garrysmod.com/page/sql/Begin[/url] If you are still not sure: They are a quick way to run BEGIN and COMMIT SQL Key works [url]http://dev.mysql.com/doc/refman/5.7/en/begin-end.html[/url][/QUOTE] 1st guy that actually helped, thanks alot! :)
Sorry, you need to Log In to post a reply to this thread.