Question

I am trying to query my mysql database. I am using the database cookbook and can setup a connection with my database. I trying to query my database for information so now the question is how do I store than information so I can access it in another resource. Where do the results of the query get stored? This is my recipe:

mysql_database "Get admin users" do
    connection mysql_connection_info
    sql "Select * from #{table_name}"
    action :query
end

Thanks in advance

Was it helpful?

Solution

If you don't have experience with Ruby, this might be really confusing. There's no way to "return" the result of a provider from a Chef resource. The mysql_database is a Chef::Recipe DSL method that gets translated to Chef::Provider::Database::Mysql at runtime. This provider is defined in the cookbook.

If you take some time to dive into that provider, you'll can see how it executes queries, using the db object. In order to get the results of a query, you'll need to create your own connection object in the recipe and execute a command against it. For example

require 'mysql'
db = ::Mysql.new('host', 'username', 'password', nil, 'port', 'socket') # varies with setup

users = db.query('SELECT * FROM users')

#
# You might need to manipulate the result into a more manageable data 
# structure by splitting on a carriage return, etc...
#
# Assume the new object is an Array where each entry is a username.
#

file '/etc/group' do
  contents users.join("\n")
end

OTHER TIPS

I find using good old Chef::Mixin:ShellOut / shell_out() fairly sufficient for this job and it's DB agnostic (assuming you know your SQL :) ). It works particularly well if all you are querying is one value; for multiple rows/columns you will need to parse the SQL query results. You need to hide row counts, column headers, eat preceding white-space, etc. from your result set to just get the query results you want. For example, below works on SQL Server :

Single item

so = shell_out!("sqlcmd ... -Q \"set nocount on; select file_name(1)\" -h-1 -W")
db_logical_name = so.stdout.chop

Multiple rows/columns (0-based position of a value within a row tells you what this column is)

so = shell_out!("sqlcmd ... -Q \"set nocount on; select * from my_table\" -h-1 -W")
rows_column_data = so.stdout.chop
# columns within rows are space separated, so can be easily parsed 
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top