fancygrid 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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