Bob
Bob

Reputation: 303

Creating prepared statements with the mysql2 ruby gem

I'm new to ruby and I thought that to help me learn I'd create a small command line script that creates database users in Mysql/MariaDB. I'm trying to use the mysql2 package however I have run into problems. Here is the code I'm having an issue with, I've stripped out all the stuff that's not relevent:

#!/usr/bin/env ruby

require 'mysql2'

root_password = 'root-pass-here'
user_name = 'jonny-5'
user_password = '5hortCi4cuit'

client = Mysql2::Client.new(:host => "localhost", :username => "root", :password => root_password)
statement = client.prepare("CREATE USER '?'@'localhost' IDENTIFIED BY '?';")
result = statement.execute(user_name, user_password)

p result

Gemfile:

source 'https://rubygems.org'

gem 'mysql2', '0.5.3'

I have tried all of these:

client.prepare("CREATE USER '?'@'localhost' IDENTIFIED BY '?';")
client.prepare("CREATE USER `?`@`localhost` IDENTIFIED BY `?`;")
client.prepare("CREATE USER (?)@'localhost' IDENTIFIED BY (?);")
client.prepare("CREATE USER ?@'localhost' IDENTIFIED BY ?;")

And get the following errors

Bind parameter count (0) doesn't match number of arguments (2) (Mysql2::Error)
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '`?`' at line 1 (Mysql2::Error)
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '(?)@'localhost' IDENTIFIED BY (?)' at line 1 (Mysql2::Error)
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '?@'localhost' IDENTIFIED BY ?' at line 1 (Mysql2::Error)

So if I use what I believe to be the correct syntax it doesn't find my quesion marks, if I use any of the others it's like it finds them but doesn't replace them before executing the query.

I am using MariaDB instead of MySQL but the mysql2 gem says it does support MariaDB. I'm running 10.4.13 which is not listed on the github page, they only go as high as 10.3, however I have tested the CREATE USER 'username'@'localhost' IDENTIFIED BY 'password'; syntax via the command line and it works so I don't think that's the issue.

Can anyone tell me where I'm going wrong?

Upvotes: 0

Views: 530

Answers (1)

nullTerminator
nullTerminator

Reputation: 396

SQL placeholders substitute the whole parameter, and they handle strings and numbers correctly. That's why they are used to prevent SQL injection. Have you tried not putting the placeholders in quotes?

statement = client.prepare('CREATE USER ? IDENTIFIED BY ?;')

new_users.each do |user|
  statement.execute("#{user}@localhost", 'pa55word')
end
# not tested, I don't have SQL installed

Upvotes: 1

Related Questions