Kurt StephensNerd Up! | ||
|
Kurt on Thu, 2006-10-26 18:53.
See: http://rubyforge.org/projects/userquery/ The RubyForge package userquery allows users to do general queries on SQL database table columns using a simple query language. The package parses tokens from the user’s query and generates SQL WHERE clauses immune to SQL injection attacks. For example, if a user wants to search for all UserQuery will intuitively convert this query into an SQL WHERE clause fragment: ( (entries.date >= '2006-11-01 00:00:00') AND (entries.date < '2006-11-02 00:00:00') ) The user query syntax includes “ To use UserQuery:
require 'user_query'
# This specifies the query schema.
s = UserQuery::Schema.
new(:table => 'entries',
:field => [ # col, type
[ :id, :number ],
[ :date, :datetime ],
[ :memo, :string ],
[ :amount, :money ]
]
)
# This represents the user's query input.
user_input = { :date => '11/1/2006' }
p = UserQuery::Parameters.new(user_input)
# Query is parsed and the SQL WHERE clause in generated.
puts s.sql(user_input, p)
The The UserQuery Parser object uses a recursive-descent parser which recognizes tokens in the user query string based on the column’s type. It generates an abstract parse tree which is then converted to SQL using the column bindings from the schema object and the data value token constants found by the parser by a Generator object. Syntax errors in the user’s input are returned in the Parameters object. A Parameters object can be used in a Rails controller to collect query input from text fields in a form template:
require 'user_query'
class EntriesController < ActionController::Base
model :entry
def index
list
render :action => 'list'
end
def list
@query = UserQuery::Parameters.new(params[:query] ||= { })
q_sql = UserQuery::Schema.
new(:table => Entry,
:field => [
# Override ActiveRecord::Base introspection:
[ :amount, :money ]
]
).sql(@query)
@entries_pages, @entries =
paginate :entries,
:class_name => 'Entry',
:per_page => 20,
:conditions => [ @q_sql ? @q_sql.gsub(/%/, '%%') : '1' ],
:order => 'id'
end
# Other methods ...
end
When an The corresponding
<%= start_form_tag :action => 'list' %>
<%= error_messages_for 'query' %>
<table class="entries_list">
<tr>
<td align="center"><%= text_field 'query', 'id', :size => 4 %></td>
<td align="center"><%= text_field 'query', 'name', :size => 10 %></td>
<td align="center"><%= text_field 'query', 'date', :size => 10 %></td>
<td align="center"><%= text_field 'query', 'memo', :size => 20 %></td>
<td align="center"><%= text_field 'query', 'amount', :size => 10 %></td>
<td align="center"><%= submit_tag 'Search' %></td>
</tr>
<tr>
<th>ID</th>
<th>Name</th>
<th>Date</th>
<th>Memo</th>
<th>Amount</th>
</tr>
<% for entry in @entries %>
<tr>
<td align="right"><%= entry.id %></td>
<td><%=h entry.name %></td>
<td><%=h entry.date.strftime("%Y/%m/%d") %></td>
<td><%=h entry.memo %></td>
<td align="right"><%=h entry.amount.format %></td>
</tr>
<% end %>
</table>
<%= end_form_tag %>
A The first file release is pending, so please visit the svn repo at: svn checkout svn://rubyforge.org/var/svn/userquery/userquery/trunk For more examples, see:
Bruce Burdick contributed the idea of inferring the Schema I’d love to hear your feedback on this module. Reply |
||
Recent comments
2 days 20 hours ago
4 weeks 5 hours ago
5 weeks 4 days ago
7 weeks 6 days ago
7 weeks 6 days ago
11 weeks 1 day ago
11 weeks 1 day ago
13 weeks 13 hours ago
13 weeks 4 days ago
13 weeks 4 days ago