0

I am executing a query and trying to store it in a constant which was working fine until I made a change to the source file today, but it's confusing to me because I didn't change the query or alter any code that interacts with this query.

Here is the code:

require 'rexml/document' include REXML def parallel_sort(data, labels) #implement a basic ruby styled selection sort in to sort the data in descending order raise "unequal arrays" if data.length != labels.length 0.upto(data.length - 2) do |i| max = i # largest value (i+1).upto(data.length - 1) { |j| max = j if data[j] > data[max] } #try to find new max data[i], data[max], labels[i], labels[max] = data[max], data[i], labels[max], labels[i] if i != max #swap values in both arrays end return (data, labels) end def process_xml_files(filenames) builds = ["Total Builds", "Failed Builds", "Successful Builds"] outFile = File.new("gchart-data.txt", "w") #outFile = File.new("parallel_sort_test.txt", "w") yearly_data = [] yearly_labels = [] monthly_data = [] monthly_labels = [] failure_data = [] failure_labels = [] failure_percents = [] hash = [] #retrieve needed data from the XML file filenames.each do |filename| #create a document doc = Document.new(File.new(filename)) doc.elements.each("//row/field") do |e| name = e.attributes['name'] text = e.text #search for tags and append correct data to lists if builds.include?(name) hash.push(name) hash.push(text) else if name == "Month-Year" yearly_labels.push(text) elsif name == "Past-Year-Builds" yearly_data.push(text) elsif name == "Month-Day" monthly_labels.push(text) elsif name == "Past-Month-Builds" monthly_data.push(text) elsif name == "Failure Type" failure_labels.push(text) else temp = 100*(text.to_f() / FAILED_BUILDS.to_f()) failure_data.push(temp) failure_percents.push(((100*temp).round/100.0).to_s() + "%") end end end end #sort the failure_percents and failure_labels arrays together failure_percents, failure_labels = parallel_sort(failure_percents, failure_labels) outFile.puts hash outFile.puts "\nYearly Data\n#{yearly_data.join(",")}" outFile.puts yearly_labels outFile.puts "\nMonthly Data\n#{monthly_data.join(",")}" outFile.puts monthly_labels outFile.puts "\nFailure Data\n#{failure_data.join(",")}" outFile.puts failure_labels.zip(failure_percents).join("|") end def execute_queries() FAILED_BUILDS = `mysql -h hostname -u root -D database -e "SELECT COUNT(id) FROM builds WHERE buildstatus = 3 AND DATE(submittime) >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR);"`.gsub!(/[A-Za-z()\s]+/,"") #get the total number of builds totalBuilds = `mysql -h hostname -u root -D database -X -e "SELECT COUNT(buildid) 'Total Builds' FROM builds WHERE DATE(submittime) >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR);" > total-builds.xml` #get the number of successful builds successBuilds = `mysql -h hostname -u root -D database -X -e "SELECT COUNT(buildid) 'Successful Builds' FROM builds WHERE buildstatus = 2 AND DATE(submittime) >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR);" > success-builds.xml` #get the number of failed builds failedBuilds = `mysql -h hostname -u root -D database -X -e "SELECT COUNT(buildid)'Failed Builds' FROM builds WHERE buildstatus = 3 AND DATE(submittime) >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR);" > failed-builds.xml` #get the number of builds per month months = `mysql -h hostname -u root -D database -X -e "select count(id) as 'Past-Year-Builds', CONCAT(SUBSTR(MONTHNAME(submittime), 1,3), '-', YEAR(submittime)) as 'Month-Year' from builds where DATE(submittime) >= DATE_SUB(CURDATE(), interval 1 year) group by YEAR(submittime), MONTH(submittime);" > year-builds.xml` days = `mysql -h hostname -u root -D database -X -e "SELECT COUNT(id) AS 'Past-Month-Builds', CONCAT(SUBSTR(MONTHNAME(submittime), 1, 3), '-', DAY(submittime)) as 'Month-Day' FROM builds WHERE DATE(submittime) >= DATE_SUB(CURDATE(), INTERVAL 30 day) GROUP BY MONTH(submittime), DAY(submittime);" > month-builds.xml` failures = `mysql -h hostname -u root -D database -X -e "select F.name 'Failure Type', count(B.id) 'Failure Count' from builds B JOIN failureareas F ON B.failurearea = F.id where Date(B.submittime) >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR) AND B.buildstatus != 2 GROUP BY F.name;" > failures.xml` end def start() #grab data from the database execute_queries() #collect the xml files from the current directory filenames = Dir.glob("*.xml") #merge the xml files together finalXML = process_xml_files( filenames ) #clean up directory filenames.each do |filename| del = `rm #{filename}` end end #test for execution if __FILE__ == $0 start() end 

So can anyone tell me why this doesn't work? I am only assigning to the constant once.

Here is the error:

gchart-url.rb:14: syntax error gchart-url.rb:75: dynamic constant assignment FAILED_BUILDS = `mysql -h hostname -u root -D database -e "SELECT COUNT(id) FROM builds WHERE buildstatus = 3 AND DATE(submittime) >= DATE_SUB(CURDATE(), INTERVAL 1 YEAR);"`.gsub!(/[A-Za-z()\s]+/,"") ^ gchart-url.rb:114: syntax error 

Any help would be great. Thanks.

EDIT: Sorry for the long post

2
  • working fine until I made a change what exactly was the change? Commented Jul 19, 2011 at 15:08
  • I added the parallel_sort method at the top of the file. Commented Jul 19, 2011 at 15:09

1 Answer 1

2

First, you should sort out the syntax errors, starting from the first reported one - often the rest will disappear.

In the line 14 change the return to return an array:

 return [data, labels] end 

Ruby thinks that you should not set a constant from a method. Setting it from a class definition (outside any 'def' block) would not be an error. If you really want to create a constant from a method, use this:

self.class.const_set(:FAILED_BUILDS, `mysql -h .... 

But my question is: why do you want to set a constant? An instance variable may be a better solution.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you. After the query is executed I extract a single number from the data and use that to perform operations. The number never changes during runs of the program, that was the reasoning behind a constant.
I would say that even in this case a variable would be better. A constant is something that is set in the source code - like the value of PI or default location of the config file, but anything that is calculated by the program is a variable - even if it is calculated only once. That's only my humble suggestion ;-)
It can be useful e.g. if you want to test an object with a high limit but don't want to iterates until you hit the limit (real world limit: 5000, testing limit: 3)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.