fancygrid 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. data/CHANGELOG +9 -2
  2. data/Gemfile +6 -9
  3. data/Gemfile.lock +88 -103
  4. data/README.md +226 -0
  5. data/ROADMAP +0 -1
  6. data/Rakefile +2 -2
  7. data/VERSION +1 -1
  8. data/app/views/fancygrid/controls.html.haml +34 -0
  9. data/app/views/fancygrid/fancygrid.html.haml +18 -0
  10. data/app/views/fancygrid/search.html.haml +24 -0
  11. data/app/views/fancygrid/sort.html.haml +8 -0
  12. data/app/views/fancygrid/table.html.haml +25 -0
  13. data/config/locales/fancygrid.de.yml +17 -19
  14. data/config/locales/fancygrid.en.yml +14 -17
  15. data/fancygrid.gemspec +48 -88
  16. data/lib/assets/javascripts/fancygrid.js +425 -0
  17. data/lib/assets/javascripts/fancygrid.min.js +15 -0
  18. data/lib/assets/stylesheets/fancygrid.css +177 -0
  19. data/lib/fancygrid.rb +63 -44
  20. data/lib/fancygrid/column.rb +165 -0
  21. data/lib/fancygrid/controller/helper.rb +46 -0
  22. data/lib/fancygrid/grid.rb +171 -317
  23. data/lib/fancygrid/node.rb +85 -490
  24. data/lib/fancygrid/object_wrapper.rb +24 -0
  25. data/lib/fancygrid/orm/active_record.rb +39 -0
  26. data/lib/fancygrid/orm/sql_generator.rb +127 -0
  27. data/lib/fancygrid/view/helper.rb +44 -0
  28. data/lib/fancygrid/view_state.rb +161 -0
  29. data/spec/column_spec.rb +29 -0
  30. data/spec/dummy/app/controllers/application_controller.rb +48 -0
  31. data/spec/dummy/app/views/application/index.html.haml +11 -0
  32. data/spec/dummy/app/views/layouts/application.html.erb +1 -1
  33. data/spec/dummy/config/application.rb +1 -1
  34. data/spec/dummy/config/environments/development.rb +2 -2
  35. data/spec/dummy/config/environments/test.rb +2 -2
  36. data/spec/dummy/config/routes.rb +3 -2
  37. data/spec/dummy/db/development.sqlite3 +0 -0
  38. data/spec/dummy/db/schema.rb +26 -0
  39. data/spec/dummy/public/javascripts/jquery-1.4.2.js +6240 -0
  40. data/spec/dummy/public/javascripts/jquery-fancygrid.js +425 -0
  41. data/spec/dummy/public/javascripts/jquery-ui.js +41 -0
  42. data/spec/dummy/public/stylesheets/fancygrid.css +183 -0
  43. data/spec/node_spec.rb +79 -301
  44. data/spec/spec_helper.rb +0 -29
  45. data/spec/view_state_spec.rb +91 -0
  46. metadata +124 -137
  47. data/.bundle/config +0 -2
  48. data/README.rdoc +0 -299
  49. data/app/views/fancygrid/_cells.html.haml +0 -13
  50. data/app/views/fancygrid/base/controls.html.haml +0 -40
  51. data/app/views/fancygrid/base/list_frame.html.haml +0 -37
  52. data/app/views/fancygrid/base/search.html.haml +0 -33
  53. data/app/views/fancygrid/base/sort.html.haml +0 -20
  54. data/app/views/fancygrid/base/table_frame.html.haml +0 -45
  55. data/config/initializers/fancygrid.rb +0 -67
  56. data/lib/fancygrid/helper.rb +0 -129
  57. data/lib/fancygrid/query_generator.rb +0 -340
  58. data/lib/fancygrid/view.rb +0 -148
  59. data/lib/generators/install_generator.rb +0 -61
  60. data/lib/generators/views_generator.rb +0 -25
  61. data/lib/version.rb +0 -0
  62. data/public/images/fancygrid/add.png +0 -0
  63. data/public/images/fancygrid/clear.png +0 -0
  64. data/public/images/fancygrid/ddn.png +0 -0
  65. data/public/images/fancygrid/dn.png +0 -0
  66. data/public/images/fancygrid/dots.png +0 -0
  67. data/public/images/fancygrid/loading.gif +0 -0
  68. data/public/images/fancygrid/magnifier.png +0 -0
  69. data/public/images/fancygrid/next.png +0 -0
  70. data/public/images/fancygrid/order.png +0 -0
  71. data/public/images/fancygrid/prev.png +0 -0
  72. data/public/images/fancygrid/reload.png +0 -0
  73. data/public/images/fancygrid/remove.png +0 -0
  74. data/public/images/fancygrid/spacer.gif +0 -0
  75. data/public/images/fancygrid/submit.png +0 -0
  76. data/public/images/fancygrid/th_bg.png +0 -0
  77. data/public/images/fancygrid/up.png +0 -0
  78. data/public/images/fancygrid/uup.png +0 -0
  79. data/public/javascripts/fancygrid.js +0 -477
  80. data/public/javascripts/fancygrid.min.js +0 -17
  81. data/public/stylesheets/fancygrid.css +0 -289
  82. data/public/stylesheets/fancygrid.scss +0 -302
  83. data/spec/dummy/log/development.log +0 -0
  84. data/spec/dummy/log/production.log +0 -0
  85. data/spec/dummy/log/server.log +0 -0
  86. data/spec/dummy/log/test.log +0 -1026
  87. data/spec/dummy/public/javascripts/application.js +0 -2
  88. data/spec/dummy/public/javascripts/controls.js +0 -965
  89. data/spec/dummy/public/javascripts/dragdrop.js +0 -974
  90. data/spec/dummy/public/javascripts/effects.js +0 -1123
  91. data/spec/dummy/public/javascripts/prototype.js +0 -6001
  92. data/spec/dummy/public/javascripts/rails.js +0 -175
  93. data/spec/grid_spec.rb +0 -15
  94. data/spec/integration/navigation_spec.rb +0 -9
  95. data/spec/query_generator_spec.rb +0 -358
@@ -1,45 +0,0 @@
1
- .fg-fancygrid{ :class => fancygrid.name }
2
- - if fancygrid.has_complex_search?
3
- = render(:template => Fancygrid.search_template, :locals => { :fancygrid => fancygrid })
4
- - if fancygrid.has_top_control?
5
- = render(:template => Fancygrid.controls_template, :locals => { :fancygrid => fancygrid, :css_class => :"controls top" })
6
-
7
- .fg-tablewrapper
8
- %table
9
- %tr.fg-header
10
- - fancygrid.each_visible_leaf do |leaf|
11
- %th{ :class => leaf.css_class, :table => leaf.record_table_name, :column => leaf.name, :order => leaf.applied_sort_order }
12
- .fg-head-wrapper.fg-order-tag
13
- = leaf.human_name
14
-
15
- - if fancygrid.has_simple_search?
16
- %tr.fg-search
17
- - fancygrid.each_visible_leaf do |leaf|
18
- %td{ :class => leaf.css_class }
19
- - next unless leaf.searchable
20
- - case leaf.search_input_kind
21
- - when :none
22
- = text_field_tag( leaf.tag_name, leaf.search_value, :class => :"fg-attribute" )
23
- - when :select
24
- = select_tag( leaf.tag_name, options_for_select(leaf.search_select_collection, :selected => leaf.search_value), :class => :"fg-attribute" )
25
-
26
- - fancygrid.each_record do |record|
27
- %tr.fg-row{ :class => fancygrid.css_proc_evaluate(record) }
28
- - fancygrid.each_visible_leaf do |leaf|
29
- %td{ :class => leaf.css_class }
30
- = render_fancygrid_leaf(record, leaf, &format_block)
31
-
32
- - if fancygrid.has_bottom_control?
33
- = render(:template => Fancygrid.controls_template, :locals => { :fancygrid => fancygrid, :css_class => :"controls bottom" })
34
- - if fancygrid.has_sort_window?
35
- = render(:template => Fancygrid.sort_template, :locals => { :fancygrid => fancygrid })
36
-
37
- - unless fancygrid.is_static?
38
- :javascript
39
- $(function(){
40
- var fancyOptions = #{fancygrid.js_options};
41
- $(".fg-fancygrid.#{fancygrid.name}").fancygrid(fancyOptions);
42
- if(!fancyOptions.isStatic){
43
- $(".fg-fancygrid.#{fancygrid.name}").fancygrid("reloadPage");
44
- }
45
- });
@@ -1,67 +0,0 @@
1
- Fancygrid.setup do |config|
2
-
3
- # The path to the table template which is rendered when the grid type is set
4
- # to :table
5
- #
6
- # config.table_template = "fancygrid/base/table_frame"
7
-
8
- # The path to the list template which is rendered when the grid type is set
9
- # to :list
10
- #
11
- # config.list_template = "fancygrid/base/list_frame"
12
-
13
- # The path to the controls template which is rendered at the top and the
14
- # bottom of a grid
15
- #
16
- # config.controls_template = "fancygrid/base/controls"
17
-
18
- # The path to the sort template which defines the view of the column sorting window
19
- #
20
- # config.sort_template = "fancygrid/base/sort"
21
-
22
- # The path to the search template which defines the view of the complex search
23
- #
24
- # config.search_template = "fancygrid/base/search"
25
-
26
- # The prefix that is used for every cells template. Default value is
27
- # "fancygrid" so every template is expected in the "/app/views/fancygrid"
28
- # directory
29
- #
30
- # config.cells_template_directory = "fancygrid"
31
-
32
- # The default cells template name. This is combined with the
33
- # 'default_cells_template_directory' to get the full template name
34
- #
35
- # config.cells_template = "_cells"
36
-
37
- # Specifies the the internationalization namespace where the plugin will
38
- # lookup for translations.
39
- #
40
- # config.i18n_scope = "fancygrid"
41
-
42
- # Value specifying whether the grid name is automatily used as template name
43
- # to render a grids cells
44
- #
45
- # config.use_grid_name_as_cells_template = false
46
-
47
- # Value specifying whether the search is visible or not when the grid is
48
- # rendered for the first time.
49
- #
50
- # config.search_visible = false
51
-
52
- # Specifies the default grid type. Available values are :table and :list
53
- # :table will render the data inside a table. Each record will get its own
54
- # table row and each attribute its own cell.
55
- # :list will render each record inside an unordered list as an li element.
56
- # you must provide a rendering block or a template to render each record.
57
- #
58
- # config.default_grid_type = :table
59
-
60
- # Default options for number of pages selection
61
- #
62
- # config.default_per_page_options = [5, 10, 15, 20, 25, 30, 40, 50]
63
-
64
- # Default value for number of pagers selection
65
- #
66
- # config.default_per_page_selection = 20
67
- end
@@ -1,129 +0,0 @@
1
- require "active_support/hash_with_indifferent_access"
2
-
3
- module Fancygrid
4
-
5
- module Helper
6
-
7
- def fancygrid_params(name)
8
- opts = params[:fancygrid] || HashWithIndifferentAccess.new({})
9
- opts[name]
10
- end
11
-
12
- def fancygrid_remote_call?(name)
13
- !fancygrid_params(name).nil?
14
- end
15
-
16
- # Creates a fancygrid instance for the given model name, its class and
17
- # its table name.
18
- # === Example
19
- # fancygrid_for :users do |grid|
20
- #
21
- # # specify attributes to display
22
- # grid.attributes( :id, :username, :email )
23
- #
24
- # # specify the callback url for ajax loading
25
- # grid.url = users_path
26
- #
27
- # # finally call find with some customized find options
28
- # grid.find( :order => "users.created_at DESC" )
29
- #
30
- # end
31
- def fancygrid_for(name, klass = nil, table_name = nil)#:yields: grid
32
- raise "block missing" unless block_given?
33
-
34
- @fancygrid ||= HashWithIndifferentAccess.new({})
35
- @fancygrid[name] ||= Grid.new(name, klass, table_name, params)
36
-
37
- fancygrid_instance = @fancygrid[name]
38
-
39
- yield fancygrid_instance
40
-
41
- view_opts = fancygrid_params(name)
42
- view_opts ||= fancygrid_instance.load_view_proc_evaluate
43
-
44
- # load the fancygrid view
45
- fancygrid_instance.load_view(view_opts || {})
46
-
47
- # store the view right back
48
- fancygrid_instance.store_view_proc_evaluate
49
-
50
- # now the fancygrid setup is complete and the view is loaded
51
- # run the database query when we are in the remote state
52
- if !fancygrid_instance.is_static? && fancygrid_remote_call?(name)
53
- fancygrid_instance.query_for_data
54
- end
55
-
56
- fancygrid_instance.sort_leafs!
57
- end
58
-
59
- # Renders an existing fancygrid for the given name. You can append a rendering block
60
- # or pass a template name as an option for custom rendering.
61
- # === Options
62
- # * <tt>data</tt> - The data to render
63
- # * <tt>template</tt> - The template to use for custom rendering columns
64
- # * <tt>url</tt> - The callback url for ajax
65
- # * <tt>search_visible</tt> - If true, the search will be visible
66
- # * <tt>hide_top_control</tt> - If true, the top control bar will be hidden
67
- # * <tt>hide_bottom_control</tt> - If true, the bottom control bar will be hidden
68
- # * <tt>grid_type</tt> - may be one of <tt>:list</tt> table <tt>:table</tt> to render a list or a table
69
- def fancygrid(name, options=nil, &block)#:yields: column, record, value
70
- store_name = name.to_s
71
- raise "Missing fancygrid for name '#{store_name}'" if(@fancygrid.nil? || @fancygrid[store_name].nil?)
72
- fancygrid_instance = @fancygrid[store_name]
73
-
74
- options ||= {}
75
- [:data, :template, :url, :search_visible, :hide_top_control,
76
- :hide_bottom_control, :grid_type, :search_formats
77
- ].each do |option|
78
- fancygrid_instance.send(option.to_s + "=", options[option]) if options[option]
79
- end
80
-
81
- format_block = block_given? ? block : nil
82
- template = Fancygrid.table_template
83
- template = Fancygrid.list_template if(fancygrid_instance.grid_type.to_s == "list")
84
-
85
- render(:template => template, :locals => {
86
- :fancygrid => fancygrid_instance,
87
- :cells_block => format_block, :format_block => format_block
88
- })
89
- end
90
-
91
- # Renders the given <tt>record</tt>, <tt>leaf</tt> and <tt>value</tt> with the
92
- # leafs template or the passed rendering block. The result is a column cell content.
93
- def format_fancygrid_value(record, leaf, value=nil, &format_block)
94
- if block_given?
95
- if defined?(Haml::Helpers) && is_haml?
96
- capture_haml(leaf, record, value, &format_block)
97
- else
98
- capture(leaf, record, value, &format_block)
99
- end
100
- else
101
- render( :template => leaf.root.template, :locals => {
102
- :grid => leaf.root, :table => leaf.root,
103
- :record => record,
104
- :cell => leaf, :column => leaf,
105
- :value => value
106
- })
107
- end
108
- end
109
- alias :fancy_rendering_for :format_fancygrid_value # backward compatibility
110
-
111
- # Returns the <tt>value</tt> of the given <tt>leaf</tt> if it is not <tt>:formatable</tt>.
112
- # Otherwie the <tt>leaf</tt> ist <tt>value</tt> and the <tt>record</tt> will
113
- # be passed to the <tt>format_fancygrid_value</tt> method to render and format
114
- # the value. The result is a column cell content.
115
- def render_fancygrid_leaf(record, leaf, &format_block)
116
- value = leaf.value_from(record)
117
- return value if(!leaf.formatable && leaf.root.grid_type == :table)
118
- format_fancygrid_value(record, leaf, value, &format_block)
119
- end
120
- alias :fancyvalue_for :render_fancygrid_leaf # backward compatibility
121
-
122
- def fancygrid_button name, translate_scope, default, alt=nil
123
- title = I18n.t(translate_scope, :default => default, :scope => Fancygrid.i18n_scope)
124
- alt ||= title
125
- image_tag('/images/fancygrid/spacer.gif', :size => '16x16', :class => "#{name} fg-button", :title => title, :alt => title ).html_safe
126
- end
127
- end
128
-
129
- end
@@ -1,340 +0,0 @@
1
- require "active_support/hash_with_indifferent_access"
2
-
3
- module Fancygrid
4
- class QueryGenerator#:nodoc:
5
-
6
- OPERATOR_NAMES = [
7
- :equal, :not_equal, :less, :less_equal, :greater, :greater_equal, :starts_with, :ends_with,
8
- :like, :is_null, :is_not_null, :is_true, :is_not_true, :is_false, :is_not_false, :in, :not_in
9
- ]
10
-
11
- attr_accessor :query, :fancygrid
12
-
13
- def initialize(options=nil, grid=nil)
14
- options ||= {}
15
- options = ActiveSupport::HashWithIndifferentAccess.new(options)
16
-
17
- self.query = {}
18
- self.fancygrid = grid
19
-
20
- self.select(options[:select])
21
- self.apply_pagination(options[:pagination])
22
- self.apply_search_conditions(options[:operator] || :and, options[:conditions])
23
- self.apply_sort_order(options[:order])
24
- end
25
-
26
- def parse_options(options=nil)#:nodoc:
27
- options ||= {}
28
- [:conditions, :order, :group, :having, :limit, :offset, :joins, :include, :select, :from, :readonly, :lock].each do |option|
29
- self.send(option, options[option]) unless options[option].nil?
30
- end
31
- end
32
-
33
- # Takes a hash like { :page => 2, :per_page => 20 } and translates it into :limit and :offset options which are
34
- # then applied to the final query
35
- #
36
- def apply_pagination(options=nil)
37
- options ||= {}
38
- options = ActiveSupport::HashWithIndifferentAccess.new(options)
39
- self.limit(options[:per_page].to_i)
40
- self.offset(options[:page].to_i * self.limit())
41
- end
42
-
43
- # Takes a hash like { :column => "users.name", :order => "asc" } and translates it into the :order option and
44
- # then applies it to the final query
45
- #
46
- def apply_sort_order(options=nil)
47
- self.order("#{options[:column]} #{options[:order].to_s.upcase}") if options
48
- end
49
-
50
- # Takes an operator and an conditions hash like { :<table> => { :<column> => [{ :oparator => <op>, :value => <value> }] } }
51
- # and converts them into a query joined by the given operator
52
- #
53
- def apply_search_conditions(operator, search_conditions)
54
- return unless search_conditions
55
-
56
- operator = logical_operator(operator)
57
-
58
- conditions = []
59
- arguments = []
60
-
61
- # backward compatibility
62
- search_conditions = search_conditions.map do |table, columns|
63
- columns.map do |column, value|
64
- if value.is_a?(Hash)
65
- if value.keys.all? { |key| key.to_s.match(/^\d+$/) }
66
- # for hashes like this
67
- # :<table> => {
68
- # :<column> => {
69
- # "0" => { :oparator => <op>, :value => <value> },
70
- # "1" => { :oparator => <op>, :value => <value> },
71
- # "2" => { :oparator => <op>, :value => <value> }
72
- # }
73
- # }
74
- #
75
- value.map{ |key, opts|
76
- { :column => "#{table}.#{column}", :operator => opts[:operator], :value => opts[:value] }
77
- }
78
- else
79
- # for hashes like this
80
- # :<table> => {
81
- # :<column> => {
82
- # :oparator => <op>, :value => <value>
83
- # }
84
- # }
85
- #
86
- { :column => "#{table}.#{column}", :operator => value[:operator], :value => value[:value] }
87
- end
88
- elsif value.is_a?(Array)
89
- # for hashes like this
90
- # :<table> => {
91
- # :<column> => {
92
- # [{ :oparator => <op>, :value => <value> },
93
- # { :oparator => <op>, :value => <value> },
94
- # { :oparator => <op>, :value => <value> }]
95
- # }
96
- # }
97
- #
98
- value.map{ |opts|
99
- { :column => "#{table}.#{column}", :operator => opts[:operator], :value => opts[:value] }
100
- }
101
- else
102
- # for hashes like this
103
- # :<table> => {
104
- # :<column> => <value>
105
- # }
106
- #
107
- unless value.blank?
108
- op = (fancygrid and fancygrid.simple_search_operator(table, column) or :like).to_s
109
- { :column => "#{table}.#{column}", :operator => op, :value => value }
110
- else
111
- nil
112
- end
113
- end
114
- end
115
- end
116
- search_conditions = search_conditions.flatten
117
-
118
- search_conditions.each do |options|
119
- next unless options
120
- sql_query, value = comparison_operator(options[:column], options[:operator], options[:value])
121
- conditions << sql_query
122
- arguments << value if (value)
123
- end
124
-
125
- conditions = [conditions.join(operator)] + arguments
126
- append_conditions(:and, conditions)
127
- end
128
-
129
- # Joins two conditions arrays or strings with the given operator
130
- #
131
- # === Example
132
- #
133
- # condition1 = ["first_name = ?", first_name]
134
- # condition2 = ["last_name = ?", last_name]
135
- #
136
- # join_conditions(:and, condition1, condition2)
137
- # # => ["(first_name = ?) AND (last_name = ?)", first_name, last_name]
138
- #
139
- def join_conditions(operator, conditions1, conditions2)
140
- conditions1 = Array(conditions1)
141
- conditions2 = Array(conditions2)
142
- operator = logical_operator(operator).gsub(" ", "")
143
-
144
- if conditions1.empty?
145
- return [] if conditions2.empty?
146
- return conditions2
147
- elsif conditions2.empty?
148
- return conditions1
149
- end
150
-
151
- left_sql = conditions1.shift
152
- right_sql = conditions2.shift
153
-
154
- if left_sql.blank?
155
- return [] if right_sql.blank?
156
- return [right_sql] + conditions2
157
- elsif right_sql.blank?
158
- return [left_sql] + conditions1
159
- end
160
-
161
- conditions = "(#{left_sql}) #{operator} (#{right_sql})"
162
- return [conditions] + conditions1 + conditions2
163
- end
164
-
165
- def append_conditions(operator, conditions)
166
- self.query[:conditions] = join_conditions(operator, self.query[:conditions], conditions)
167
- end
168
-
169
- # An SQL fragment like “administrator = 1”, ["user_name = ?", username], or ["user_name = :user_name", { :user_name => user_name }]
170
- #
171
- def conditions(conditions=nil)
172
- if conditions
173
- append_conditions(:and, conditions)
174
- end
175
- self.query[:conditions]
176
- end
177
-
178
- # An SQL fragment like “created_at DESC, name”.
179
- #
180
- def order(order_by=nil)
181
- self.query[:order] = order_by if order_by
182
- self.query[:order]
183
- end
184
-
185
- # An SQL fragment like “created_at DESC, name”.
186
- #
187
- def group(group_by=nil)
188
- self.query[:group] = group_by if group_by
189
- self.query[:group]
190
- end
191
-
192
- # An attribute name by which the result should be grouped. Uses the GROUP BY SQL-clause.
193
- #
194
- def having(having_sql=nil)
195
- self.query[:having] = having_sql if having_sql
196
- self.query[:having]
197
- end
198
-
199
- # An integer determining the limit on the number of rows that should be returned.
200
- #
201
- def limit(num=nil)
202
- self.query[:limit] = num if num
203
- self.query[:limit]
204
- end
205
-
206
- # An integer determining the offset from where the rows should be fetched. So at 5, it would skip rows 0 through 4.
207
- #
208
- def offset(num=nil)
209
- self.query[:offset] = num if num
210
- self.query[:offset]
211
- end
212
-
213
- # Either an SQL fragment for additional joins like “LEFT JOIN comments ON comments.post_id = id” (rarely needed),
214
- # named associations in the same form used for the :include option, which will perform an INNER JOIN on the
215
- # associated table(s), or an array containing a mixture of both strings and named associations. If the value is a
216
- # string, then the records will be returned read-only since they will have attributes that do not correspond to the
217
- # table’s columns. Pass :readonly => false to override.
218
- #
219
- def joins(to_join_with=nil)
220
- self.query[:joins] = to_join_with if to_join_with
221
- self.query[:joins]
222
- end
223
-
224
- # Names associations that should be loaded alongside. The symbols named refer to already defined associations.
225
- # See eager loading under Associations.
226
- #
227
- def include(to_include=nil)
228
- self.query[:include] = to_include if to_include
229
- self.query[:include]
230
- end
231
-
232
- # By default, this is “*” as in “SELECT * FROM”, but can be changed if you, for example, want to do a join but not
233
- # include the joined columns. Takes a string with the SELECT SQL fragment (e.g. “id, name”).
234
- #
235
- def select(select = nil)
236
- if select
237
- self.query[:select] = Array(self.query[:select])
238
- self.query[:select] |= Array(select)
239
-
240
- if self.query[:select].include?("*")
241
- self.query[:select] = ["*"]
242
- end
243
- end
244
- self.query[:select]
245
- end
246
-
247
- # By default, this is the table name of the class, but can be changed to an alternate table name
248
- # (or even the name of a database view).
249
- #
250
- def from(table_name=nil)
251
- self.query[:from] = table_name if table_name
252
- self.query[:from]
253
- end
254
-
255
- # Mark the returned records read-only so they cannot be saved or updated.
256
- #
257
- def readonly(value=nil)
258
- self.query[:readonly] = value unless value.nil?
259
- self.query[:readonly]
260
- end
261
-
262
- # An SQL fragment like “FOR UPDATE” or “LOCK IN SHARE MODE”. :lock => true gives connection’s default exclusive
263
- # lock, usually “FOR UPDATE”.
264
- #
265
- def lock(value=nil)
266
- self.query[:lock] = value unless value.nil?
267
- self.query[:lock]
268
- end
269
-
270
- private
271
- def comparison_operator(column, operator, value)
272
- operator = case operator.to_s
273
- when "equal"
274
- "="
275
- when "not_equal"
276
- "!="
277
- when "less"
278
- "<"
279
- when "less_equal"
280
- "<="
281
- when "greater"
282
- ">"
283
- when "greater_equal"
284
- ">="
285
- when "starts_with"
286
- value = "#{value.to_param}%"
287
- "LIKE"
288
- when "ends_with"
289
- value = "%#{value.to_param}"
290
- "LIKE"
291
- when "like"
292
- value = "%#{value.to_param}%"
293
- "LIKE"
294
- when "is_null"
295
- value = nil
296
- "IS NULL"
297
- when "is_not_null"
298
- value = nil
299
- "IS NOT NULL"
300
- when "is_true"
301
- value = nil
302
- "IS TRUE"
303
- when "is_not_true"
304
- value = nil
305
- "IS NOT TRUE"
306
- when "is_false"
307
- value = nil
308
- "IS FALSE"
309
- when "is_not_false"
310
- value = nil
311
- "IS NOT FALSE"
312
- when "in"
313
- value = value.split(",")
314
- "IN"
315
- when "not_in"
316
- value = value.split(",")
317
- "NOT IN"
318
- else
319
- "="
320
- end
321
-
322
- if value.nil?
323
- return "( #{column} #{operator} )", value
324
- else
325
- return "( #{column} #{operator} (?) )", value
326
- end
327
-
328
- end
329
-
330
- def logical_operator(name)
331
- case name.to_s
332
- when "all", "and"
333
- " AND "
334
- else
335
- " OR "
336
- end
337
- end
338
-
339
- end
340
- end