Otherwise it just downloads an html file which is obviously why it doesn't work.
Otherwise it just downloads an html file which is obviously why it doesn't work.
Nevermind me! I fixed it. The issue was when I initially downloaded the files through wget, I didn't specify the raw URL. It downloaded html instead.
I retried it with the so.18.3.0, but it only worked with the so.18, so I used that one.
Linux install for those who also might want it, where server_1 is your root folder with srcds_linux:
Thanks sly0rCode:cd ~/server_1 wget https://raw.githubusercontent.com/syl0r/MySQLOO/master/MySQL/lib/linux/libmysqlclient.so.18 chmod +x ./libmysqlclient.so.18 cd ./garrysmod/lua mkdir -p bin cd ./bin wget https://raw.githubusercontent.com/syl0r/MySQLOO/master/out/linux/gmsv_mysqloo_linux.dll chmod +x ./gmsv_mysqloo_linux.dll
A few years ago, I used to use MySQLOO 8 for my server (circa 2013), but switched over to tmysql4 after experiencing the utterly depressing performance and lack of stability MySQLOO had at the time.
I understand that MySQLOO has been greatly rewritten for this version update, so seeing as tmysql4 is no longer actively developed, nor does it have prepared statements or ensured query execution order, in what ways/in what scenarios is MySQLOO 9 slower than tmysql4? Furthermore, how stable is it as it stands right now?
You should never notice any speed difference between mysqloo and tmysql except for the fact that tmysql used two connections per database instance (which is a bad thing).
The current mysqloo9 version should be perfectly stable. I run it on my own server since ~1 year and I haven't noticed any crashes caused by it. I will probably release an update to the module today or tomorrow that is going to change a lot of things (while maintaining full backwards compatibility) but even that should be mostly stable.
If you do however notice any crashes that you think might be related to this module feel free to post about it in this thread.
Hey, anyone here who could help me with a little problem with this version of mysqloo?
I'm not sure if I'm using the database:ping() correctly.. currently I don't see any way to reconnect to a database after the connection is lost while server is on.
I posted a thread here, please see for further information:
To fix your problem you have to recreate the db using mysqloo.connect() if the connection fails.
I also just released a new update that changes many things, the most important being that you can reuse query objects and start them multiple times:
local query = db:query("UPDATE counter_tbl SET counter = counter + 1") query:start() query:start()
This is especially useful for prepared queries as they can reuse the statement handle allocated on the database server:
local query = db:prepare("INSERT INTO logs (`message`) VALUES(?)") query:setString(1, "hello") query:start() query:setString(2, "world") query:start()
It even calls the callbacks you'd expect every time as long as you always set the callbacks before you start the query.
local ply1 = player.GetAll() local query = db:prepare("SELECT rank FROM users WHERE steamid = ?") query:setString(1, ply1:SteamID()) function query:onSuccess(data) //This will set the rank of ply1 ply1:SetRank(data.rank) end query:start() local ply2 = player.GetAll() query:setString(1, ply2:SteamID()) function query:onSuccess(data) //This will set the rank of ply2 ply2:SetRank(data.rank) end query:start()
The update notes said that prepared queries can now return multiple result sets, however when trying to do something such as
I getCode:local a = database:prepare "SELECT 1, 2; SELECT 3, 4" function a:onError(err, sql) MsgN(err, "\n\n", sql) end function a:onSuccess(data) while self:hasMoreResults() do PrintTable(data) data = self:getNextResults() end end a:start()
Prepared statements can only ever represent one statement (hence the name).
You can still get multiple result sets without having multiple statements by calling a stored procedure.
So I would recommend either creating a stored procedure that does what you want or to use two prepared queries in a transaction.
It still keeps printing "false" with the db:ping() all the time while my databse is online and I can access it fine on phpMyAdmin. (And so can the server if it's started while database is already online)db = mysqloo.connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME, DATABASE_PORT) db:connect()
Then you must have wrong credentials. Try printing the error message.
The error message from db:onConnectionFailed is always the same, whether my databse is online or offline.
"Can't connect to MySQL server on 'localhost'"
Also I'll just clarify again, this only occurs if I start server while database is offline. Otherwise it works.
require ("mysqloo") local DATABASE_HOST = "localhost" local DATABASE_PORT = 3306 local DATABASE_NAME = "bleur" local DATABASE_USERNAME = "root" local DATABASE_PASSWORD = "pass" local db = mysqloo.connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME, DATABASE_PORT) function db:onConnected( ) if timer.Exists("pingdb") then timer.Remove("pingdb") end MsgC( Color( 255, 255, 0 ), "Successfully connected to the MySQL Database\n" ) end function db:onConnectionFailed( err ) MsgC( Color( 255, 255, 0 ), "Connection to the MySQL Database failed\nError: ", err, "\n") timer.Create("pingdb", 5, 0, function() print("Retrying connection to database...") db = mysqloo.connect(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME, DATABASE_PORT) db:connect() db:ping() print (db:ping(),"\n") end) end db:connect()
The problem is that you are creating a new database instance but you aren't setting the callbacks again. This will mean onConnected will not be called and your timer will just retry every 5 seconds.
Additionally db:ping() does only work _after_ the connection has been established. Since db:connect() doesn't wait for the connection to finish db:ping() will probably run before that and return false every time.
So I'm working on the next update for my addon. I set up a MySQL database on my home server, and this query is erroring.
The error isCode:CREATE TABLE IF NOT EXISTS arcbank_log ( transaction_id UNSIGNED BIGINT NOT NULL AUTO_INCREMENT, timestamp UNSIGNED BIGINT NOT NULL, account1 varchar(255) NOT NULL, account2 varchar(255) NOT NULL, user1 varchar(255) NOT NULL, user2 varchar(255) NOT NULL, moneydiff INT NOT NULL, money BIGINT, transaction_type UNSIGNED SMALLINT NOT NULL, comment varchar(255) NOT NULL );
So, for some reason my query is getting truncated. Why would that be?Code:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNSIGNED BIGINT NOT NULL AUTO_INCREMENT, timestamp UNSIGNED BIGINT NOT NULL, acc' at line 3
That's how the syntax looks like it's supposed to be based on sections like https://dev.mysql.com/doc/refman/5.7...-overview.html
Edit: I'm not sure how I didn't realize you answered before me Thomas, I swear I didn't see it
You are all correct! :)
And yes, I needed to set the primary key too. While I was at it I set the charset to utf8.
Fuck me, somehow I overwrite the v9 binary with v8
That seems to be a problem with all binary modules (at least the ones I tested).
Besides that I don't see any point using mysqloo in a coroutine since all of its functions are async anyways (except for query:wait()).
Fuck me, somehow I overwrite the v9 binary with v8
The dbal code itself doesn't get any nicer, I'll agree, but the intent was to make the gamemode that uses it cleaner -- run it in a coroutine and call db:Query() as much as you like instead of creating a whole bunch of local callbacks and chaining them together. Looks like I'll have to spend some time tinkering.
edit: turns out I accidentally overwrote v9 with v8 at some point, fuck my life
I'm inexperienced in the details of how a program communicates with its database. Would I be correct to assume that this cannot communicate with postgres? Would I be correct in assuming this *can* communicate with MariaDB? I'm looking to reorganize my system and move my MySQL database and I'd like to go to postgres but I recognize it's very possible that won't work, so I'm prepared to move to MariaDB.
You'd be correct. MariaDB is mostly compatibly with mysql (as it is a fork of mysql). Postgresql on the other hand is very different than mysql and they do not use the same protocol.
Right. On one hand I was thinking "Why not? It's the same SQL query and it's not likely anybody in gmod is using any fancy features" but then I remembered the dependency on libmysql and I figured there was some deeper shenanigans going on.
I'm probably going to be laughed at, but how difficult would it be to convert and compile the source to 64bit? Before people start on about source not being 64bit, I'm not using it for gmod.
It should be quite easy since I don't believe I am using anything specific to 32 bits. Of course you need to change all libraries to be 64 bit, but that should be doable.
If you aren't using it with gmod, then you'd also have to replace the gmod lua headers with something that emulates gmod's behaviour. If you don't want to do that yourself feel free to pm me, I can provide you with one that should work.
Hi im having errors with mysqloo. Even though i installed both the binary file and the lib file, im still having errors with darkrp not recognising the module. here is the error message i received. Any help will be appriciated
ERROR] gamemodes/darkrp/gamemode/libraries/mysqlite/mysqlite.lua:131: Could not find a suitable MySQL module. Supported modules are MySQLOO and tmysql4.
1. error - [C]:-1
2. loadMySQLModule - gamemodes/darkrp/gamemode/libraries/mysqlite/mysqlite.lua:131
3. unknown - gamemodes/darkrp/gamemode/libraries/mysqlite/mysqlite.lua:144
4. include - [C]:-1
5. unknown - gamemodes/darkrp/gamemode/init.lua:42
6. DeriveGamemode - [C]:-1
That means you didn't place the file in the correct location, it has to go in the lua/bin folder.
Seems Query:error() returns no value even when the query has errored
Now it works when used inside of the onError called for queries, however it seems when the query is apart of a transaction it doesn't.
Not really needed considering we already have the error from the callback, though it'd be useful in figuring out which query caused the error.Code:local t = database:createTransaction() local q = database:query "yes" t:addQuery(q) function t:onSuccess() print "ok" end function t:onError(err) print(self:getQueries():error()) end t:start()
Say I have a function to take money from a player. The function returns true or false to indicate whether the money was actually taken.
local moneyquery = db:prepare("UPDATE users SET money = ? WHERE steamid = ?") function PLAYER:TakeMoney(amt) if self.Money < amt then return false end local x = self.Money - amt moneyquery:setNumber(1,x) moneyquery:setString(2,self:SteamID64()) moneyquery:start() local status = false function moneyquery:onSuccess() --TakeMoney should return true now because the money operation was successful self.Money = x status = true end function moneyquery:onError(e) --TakeMoney should return false now because the money operation failed at the database status = false end return status end
This is just an example I thought of while I'm at work, but is there a better way to accomplish what I am trying to do?
The function you wrote will always return false because mysqloo is asynchronous.
This means that the moneyquery:start() call returns immediately and the callbacks are called at some point later (but definitely after you return the status).
You have three options:
1. Use query:wait(): This will pause the gmod server until the query completed, and the callbacks have been called. This is only really a possibility if the database is hosted on the same machine because otherwise it is going to cause some major lag and will leave you vulnerable to DOS attacks.
2. Design your code in a way that works with the queries being asynchronous:
An example of this would be adding a callback to your TakeMoney function that is called from one of the query callbacks:
Unfortunatley this might make your code a bit more verbose and is generally not as easy to do, but it's the safer option.function PLAYER:TakeMoney(amt, callback) if self.Money < amt then return false end local x = self.Money - amt moneyquery:setNumber(1,x) moneyquery:setString(2,self:SteamID64()) function moneyquery:onSuccess() self.Money = x callback(true) end function moneyquery:onError(e) callback(false) end moneyquery:start() end
3. You could ignore the possibility of anything going wrong because in almost all cases nothing will go wrong (unless the db goes down). This is of course not safe at all but might unclutter your code by a lot.
Personally I am using a mix of approach 2. and 3. but ideally you should always go for 2.
On a sidenote: you should always assign the callbacks to the query before you start the query, especially when you are reusing the query. Otherwise mysqloo might call the wrong callback.
On Windows, trying to escape seemingly anything other than a string will crash the server (i.e. numbers, tables, entities, and particularly nil). I'm not exactly sure where the exception is getting thrown, since it seems like the escape method is handling it, but SRCDS crashes immediately afterward:
In most cases this isn't much of an issue, but accidentally trying to escape nil (as might occur in certain scenarios) will lead to a lot of unexplainable crashes to the end-user. Having it only error in the Lua state would be much more preferable.Code:> db:escape()... [ERROR] lua_run:1: bad argument #1 to 'escape' (string expected, got no value) 1. unknown - [C]:-1 2. escape - [C]:-1 3. unknown - lua_run:1