repertoire-faceting 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
data/FAQ CHANGED
@@ -1,5 +1,14 @@
1
1
  = Repertoire Faceting FAQ =
2
2
 
3
+ = Related questions
4
+
5
+ Q. Rails 3 refuses to update schema.rb because with my fulltext index columns.
6
+
7
+ A. Put the following line in environment.rb:
8
+
9
+ config.active_record.schema_format = :sql
10
+
11
+
3
12
  = About facet indexing and the signature SQL type =
4
13
 
5
14
  Q. What's the scalability of this thing?
@@ -18,6 +27,12 @@ A. Did you remember to call expand_nesting(<facet index table>, <facet name>) af
18
27
 
19
28
  = About the ajax faceting widgets =
20
29
 
30
+ Q. A web page from the default Rails app refuses to load the faceting widgets.
31
+
32
+ A. Repertoire Faceting widgets are based on JQuery, which is incompatible with Prototype. You should remove
33
+ prototype.js and rails.js from the javascripts directory, and delete the <%= javascript_include_tag :defaults %>
34
+ line from application.html.erb.
35
+
21
36
  Q. How do I send page-specific data (for example, a search field) to the webservice with the facet widgets' data?
22
37
 
23
38
  A. If you provide a function to the facet_context plugin, it will merge the params you return before dispatching to
data/INSTALL CHANGED
@@ -7,53 +7,55 @@
7
7
 
8
8
  { install native bitset extensions }
9
9
  $ bundle install
10
- $ rake faceting:postgres:install { & provide sudo your password }
11
- $ createlang plpgsql <database> -U<username>
12
- $ psql -f $(pg_config --sharedir)/contrib/signature.sql -U<username> <database>
10
+ $ rake db:faceting:build { provide sudo your password }
11
+ $ rake db:faceting:load
13
12
 
14
13
  { in ./app/models/some_model.rb }
15
14
  class SomeModel
16
- include Repertoire::Faceting::Model // 2
17
- facet :some_column // 3
15
+ include Repertoire::Faceting::Model // 2
16
+ facet :some_column // 3
18
17
  end
19
18
 
20
19
  { in ./app/controllers/some_controller]
21
20
  class SomeController
22
- include Repertoire::Faceting::Controller // 4
23
- def base; return SomeModel; end // 5
21
+ include Repertoire::Faceting::Controller // 4
22
+ def base; return SomeModel; end // 5
24
23
  end
25
24
 
26
25
  { in ./config/routes.rb }
27
26
  SomeApp::Application.routes.draw do
28
- faceting_for :some_model // 6
27
+ faceting_for :some_model // 6
29
28
  end
30
29
 
31
30
  { in ./public/javascripts/application.js }
32
- //= require <rep.faceting> // 7
31
+ //= require <rep.faceting> // 7
33
32
 
34
33
  { in ./app/views/some_controller/index.html.erb }
35
34
  <script language="javascript">
36
35
  $().ready(function() {
37
- $('#paintings').facet_context(function() { return { } }); // 8
38
- $('.facet').facet(); // 9
39
- $('#results').results(); // 10
36
+ $('#paintings').facet_context(); // 8
37
+ $('.facet').facet(); // 9
38
+ $('#results').results(); // 10
40
39
  });
41
40
  </script>
42
- <div id='paintings'>
43
- <div id='genre' class='facet'></div>
44
- <div id='results'></div>
41
+ <div id='paintings'> // 11
42
+ <div id='genre' class='facet'></div> // 12
43
+ <div id='results'></div> // 13
45
44
  </div>
46
45
 
47
- ... that's a complete faceted browser in only 10 new lines of code in your app!
46
+ ... that's a complete faceted browser in only 13 new lines of code in your app!
48
47
 
49
- In production, you will want to start compressing the facet widgets:
48
+ In production, you will want to compress the javascript facet widgets:
50
49
 
51
50
  { in ./config/environments/production.rb }
52
51
  config.repertoire_assets.compress = true
53
52
 
54
- And to add facet indexing (scalable to a million items out of the box):
53
+ Additionally, you may wish to index the facets. At the console or in a migration:
55
54
 
56
- $ rails generate migration add_facet_index
55
+ SomeModel.update_indexed_facets([:some_column])
56
+
57
+ The faceting subsystem automatically detects available facet indices and uses
58
+ them when appropriate.
57
59
 
58
60
 
59
61
  == Detailed version.
@@ -64,7 +66,8 @@ Start with a working Rails 3 application with a PostgreSQL database.
64
66
 
65
67
  gem 'repertoire-faceting'
66
68
 
67
- * Make sure you use Rails version 3.0.2+, which adopted Arel 2.0.1. If necessary you can pull rails, arel, and rack from git.
69
+ * Make sure you use Rails version 3.0.2+, which adopted Arel 2.0.1. If necessary
70
+ you can pull rails, arel, and rack from git.
68
71
 
69
72
  gem 'rails', :git => 'git://github.com/rails/rails.git'
70
73
  gem 'arel', :git => 'git://github.com/rails/arel.git'
@@ -74,29 +77,31 @@ Start with a working Rails 3 application with a PostgreSQL database.
74
77
 
75
78
  $ bundle install
76
79
 
77
- * From your application root, build and install the repertoire-faceting native extensions to PostgreSQL. These provide
78
- a bitwise signature type used to index facets.
80
+ * From your application root, build and install the repertoire-faceting native
81
+ extensions to PostgreSQL. These provide a bitwise signature type used to
82
+ index and count facets.
79
83
 
80
- $ rake faceting:postgres:install { sudo will prompt you for your password }
84
+ $ rake db:faceting:build { sudo will prompt you for your password }
81
85
 
82
- * Load the extension into application database. Change depending on your postgres configuration:
86
+ * Load the extension into your local application database. This ensures the
87
+ plpgsql language is installed, and loads (or re-loads) the new bitset signature
88
+ type.
83
89
 
84
- $ createlang plpgsql <database> -U<username>
85
- $ psql -f $(pg_config --sharedir)/contrib/signature.sql -U<username> <database>
90
+ $ rake db:faceting:load
86
91
 
87
- You can confirm the module installed as follows. The database server may need to be restarted first.
92
+ You can confirm the module is installed as follows.
88
93
 
89
94
  $ psql -c "SELECT count('101010101'::signature);" -U<username> <database>
90
-
91
- If the module installed correctly, psql will respond with "5".
92
95
 
93
- * Install the faceting mixin in your Rails model and declare a facet on an existing database column. (See the README for complete
94
- configuration options for facets.) [ ./app/models/painting.rb ]
96
+ * Install the faceting mixin in your Rails model and declare a facet on an
97
+ existing database column. (See the README for complete configuration options
98
+ for facets.)
95
99
 
96
- class Painting
97
- include Repertoire::Faceting::Model
98
- facet :genre
99
- end
100
+ { ./app/models/painting.rb }
101
+ class Painting
102
+ include Repertoire::Faceting::Model
103
+ facet :genre
104
+ end
100
105
 
101
106
  * Test doing facet count and result queries:
102
107
 
@@ -112,60 +117,71 @@ Start with a working Rails 3 application with a PostgreSQL database.
112
117
  > Painting.where(["title like ?", 'Moon%']).count(:genre)
113
118
  => {"Impressionist"=>1}
114
119
 
115
- * Add faceting webservices to your controller and define base() to indicate which model to base queries on [ ./app/controllers/paintings_controller]
120
+ * Add faceting webservices to your controller and define base() to indicate which model to base queries on
116
121
 
117
- class PaintingsController
118
- include Repertoire::Faceting::Controller
122
+ { ./app/controllers/paintings_controller }
123
+ class PaintingsController
124
+ include Repertoire::Faceting::Controller
119
125
 
120
- def base
121
- search = "%#{params[:search]}%"
122
- Painting.where(["title like ?", search])
126
+ def base
127
+ search = "%#{params[:search]}%"
128
+ Painting.where(["title like ?", search])
129
+ end
123
130
  end
124
- end
125
131
 
126
- * Add faceting routes to your application. [ ./config/routes.rb ]
132
+ * Add faceting routes to your application.
127
133
 
128
- PaintingsApp::Application.routes.draw do
129
- faceting_for :paintings # NB must be BEFORE any resources!
130
- ...
131
- end
134
+ { ./config/routes.rb }
135
+
136
+ PaintingsApp::Application.routes.draw do
137
+ faceting_for :paintings # NB must be BEFORE any resources!
138
+ ...
139
+ end
132
140
 
133
141
  Confirm they load:
134
142
 
135
143
  $ rake routes
136
- ...
137
- /paintings/counts/:facet(.:format) {:controller=>"paintings", :action=>"counts"}
138
- paintings_results /paintings/results(.:format) {:controller=>"paintings", :action=>"results"}
139
- ...
144
+ ...
145
+ /paintings/counts/:facet(.:format) {:controller=>"paintings", :action=>"counts"}
146
+ paintings_results /paintings/results(.:format) {:controller=>"paintings", :action=>"results"}
147
+ ...
140
148
 
141
- * Load the javascript facet widgets in your main javascript file. The repertoire-assets subsystem will locate the
142
- widgets in the repertoire-faceting rubygem and load them as appropriate.
149
+ * Load the javascript facet widgets in your main javascript file. The
150
+ repertoire-assets subsystem will locate the widgets in your application's
151
+ rubygems, and load them as appropriate.
143
152
 
144
- [ ./public/javascripts/application.js ]
153
+ { ./public/javascripts/application.js }
145
154
  ...
146
155
  //= require <rep.faceting>
147
156
  ...
148
157
 
149
- * Add facet count and result widgets to your HTML page. The facet context div collects widgets that affect the same
150
- query together. (For complete options, see the README )
158
+ N.B. Repertoire Faceting widgets are based on JQuery, which is incompatible
159
+ with Prototype. If you have not already done so, you should remove
160
+ prototype.js and rails.js from the javascripts directory, and delete the
161
+ "<%= javascript_include_tag :defaults %>" line from application.html.erb.
151
162
 
152
- [ ./app/views/paintings/index.html.erb ]
163
+ * Add facet count and result widgets to your HTML page. The facet context div
164
+ collects widgets that affect the same query together. (For complete options,
165
+ see the README )
153
166
 
154
- <script language="javascript">
155
- $().ready(function() {
156
- $('#paintings').facet_context(function() { return { } });
157
- $('.facet').facet();
158
- $('#results').results();
167
+ { ./app/views/paintings/index.html.erb }
168
+
169
+ <script language="javascript">
170
+ $().ready(function() {
171
+ $('#paintings').facet_context();
172
+ $('.facet').facet();
173
+ $('#results').results();
159
174
  });
160
175
  </script>
161
176
  <div id='paintings'>
162
- <div id='genre' class='facet'></div>
163
- <div id='results'></div>
164
- </div>
177
+ <div id='genre' class='facet'></div>
178
+ <div id='results'></div>
179
+ </div>
165
180
 
166
- * If you don't already have one, create a partial for displaying your model in results lists.
181
+ * If you don't already have one, create a partial for displaying your model in
182
+ results lists.
167
183
 
168
- [ ./app/views/paintings/_painting.html.erb ]
184
+ { ./app/views/paintings/_painting.html.erb }
169
185
 
170
186
  <div class='painting' style='width:235px; margin-bottom:5px; padding:2px; border:dotted 1px;'>
171
187
  <div>Title: <%= painting.title %></div>
@@ -173,29 +189,38 @@ Start with a working Rails 3 application with a PostgreSQL database.
173
189
  <div>Genre: <%= painting.genre %></div>
174
190
  </div>
175
191
 
176
- * Configure the repertoire-assets module that loads the javascript faceting widgets to compress in
177
- production. [ ./config/environments/production.rb ]
192
+ * [ Optional ] Configure the repertoire-assets module that loads the javascript
193
+ faceting widgets to compress the widget code in production.
178
194
 
179
- PaintingsApp::Application.configure do
180
- ...
181
- config.repertoire_assets.compress = true
182
- ...
183
- end
195
+ { ./config/environments/production.rb }
184
196
 
185
- * [ Optional ] Add bitset indexes to some facets on your model. The module will automatically
186
- use facet indexes when they are available.
197
+ PaintingsApp::Application.configure do
198
+ ...
199
+ config.repertoire_assets.compress = true
200
+ ...
201
+ end
187
202
 
188
- class AddFacetIndex < ActiveRecord::Migration
189
- def self.up
190
- Painting.update_indexed_facets([:genre])
191
- end
203
+ * [ Optional ] Add bitset indexes to some facets on your model. The module will
204
+ automatically use facet indexes when they are available. Facet indexes scale
205
+ out of the box to over a million model items, and require no additional
206
+ configuration.
207
+
208
+ $ rails generate migration AddFacetIndex
209
+
210
+ { ./db/migrate/<your date>add_facet_index.rb }
211
+ class AddFacetIndex < ActiveRecord::Migration
212
+ def self.up
213
+ Painting.update_indexed_facets([:genre])
214
+ end
215
+
216
+ def self.down
217
+ Painting.update_indexed_facets
218
+ end
219
+ end
192
220
 
193
- def self.down
194
- Painting.update_indexed_facets
195
- end
196
- end
221
+ * [ Optional ] Periodically update indexes via a crontab task.
197
222
 
198
- * [ Optional ] Periodically update indexes via a crontab task. [ ./lib/tasks/update_facets.rake ]
223
+ { ./lib/tasks/update_facets.rake }
199
224
 
200
225
  task :reindex_facets => :environment do
201
226
  Painting.update_indexed_facets
data/README CHANGED
@@ -1,3 +1,30 @@
1
+ == Deployment
2
+
3
+ * repertoire-assets compression
4
+
5
+ * deploying native extensions to server
6
+
7
+ * sub-uris
8
+
9
+ * do NOT use schema.rb with repertoire-faceting
10
+
11
+
12
+ == Running unit tests
13
+
14
+ You can run the unit tests from the module's root directory. You will need a
15
+ local PostgreSQL superuser role with your unix username (use 'createuser -Upostgres').
16
+
17
+ $ bundle install
18
+ $ rake db:faceting:build { sudo will prompt for your password }
19
+ $ rake db:create
20
+ $ rake test
21
+
22
+
23
+ == Known issues
24
+
25
+ - Running the unit tests issues warnings about a circular require. These can be ignored.
26
+
27
+
1
28
  == Updating Indices
2
29
 
3
30
  Depending on how frequently you need to update facet indices, there are several options.
@@ -11,7 +38,7 @@ Depending on how frequently you need to update facet indices, there are several
11
38
  Nobelist.update_indexed_facets([:degree, :discipline])
12
39
  end
13
40
 
14
- Configure your system-level crontab task to run 'rake reindex' at the required interval.
41
+ Then configure your system-level crontab task to run 'rake reindex' at the required interval.
15
42
 
16
43
  (2) Using Repertoire's postgresql-crontab functionality
17
44
 
@@ -37,7 +64,17 @@ Depending on how frequently you need to update facet indices, there are several
37
64
  create a migration with the same calls as the rake task.
38
65
 
39
66
 
40
-
67
+
68
+ == Deployment
69
+
70
+ Because repertoire-faceting depends on a native shared library loaded by the
71
+ PostgreSQL server, the first time you deploy you will need to build and install
72
+ the extension.
73
+
74
+ <server>$ bundle install --deployment
75
+ <server>$ export RAILS_ENV=production
76
+ <server>$ rake db:facetinginstall
77
+ <server>$ rake db:facetingload
41
78
 
42
79
 
43
80
 
@@ -46,7 +83,7 @@ Rails3 documentation revisions
46
83
 
47
84
  - requires ruby 1.9.2 (ordered hashes)
48
85
  - include_root_in_json = false
49
- - rake faceting:postgres:install, :load
86
+ - rake db:facetingpostgres:install, :load
50
87
 
51
88
  To cover in the README:
52
89
 
@@ -89,145 +126,6 @@ API for faceted browsing within PostgreSQL, with extensions for Merb and jquery
89
126
  - nested facet values kept as arrays
90
127
  - update facet index (a) explicitly, (b) using Repertoire's crontab sweeper, or (c) both
91
128
 
92
-
93
- ===== Installation =====
94
-
95
- -Proviso-. You must already have PostgreSQL installed, and pg_config should display the correct values for the version of postgres you intend to use.
96
-
97
- 1. Install the repertoire-faceting gem from source
98
- [ once it's released open-source, this will be possible from github or rubyforge ]
99
-
100
- 2. Install Repertoire crontab support
101
- [ see documentation for the repertoire-devtools gem for this ]
102
-
103
- 3. Load the faceting sql extensions into your project's database
104
-
105
- - If your project shares the database with others (as in Repertoire), it's best to install by hand.
106
-
107
- psql -Upostgres <your database> -f /opt/local/share/postgresql84/contrib/signature.sql
108
-
109
- Note that the sql extensions are global to your entire database, since they land in the public schema.
110
-
111
- - If your project owns the entire database, you can use a migration:
112
-
113
- migration 1, :install_signature do
114
- sharedir = /SHAREDIR = (.*)/.match(`pg_config`)[1] # e.g. "/opt/local/share/postgresql84"
115
-
116
- up do
117
- execute File.read("#{sharedir}/contrib/signature.sql")
118
- end
119
- down do
120
- execute File.read("#{sharedir}/contrib/uninstall_signature.sql")
121
- end
122
- end
123
-
124
-
125
- ===== DataMapper extensions =====
126
-
127
- *Setup*
128
-
129
- -Proviso-. The faceting library does not yet support automigration. The best approach is to maintain your facet indices using
130
- explicit migrations as your datamapper models change.
131
-
132
- Make sure the columns you wish to facet over are indexed. For a complete description, see the section "PostgreSQL extensions." Simple example for use in a datamapper migration:
133
-
134
- migration 5, :add_facet_indices do
135
- up do
136
- execute <<-SQL.compress_lines
137
- INSERT INTO crontab(notice, role, task, interval)
138
- VALUES ('Update Project facets', NULL, $$
139
- SELECT renumber_table('project', '_packed_id');
140
- SELECT recreate_table('_project_status_facet', 'SELECT status, signature(_packed_id) FROM project GROUP BY status');
141
- $$, '5 minutes');
142
- SQL
143
- end
144
- down do
145
- execute <<-SQL.compress_lines
146
- DELETE FROM crontab WHERE notice = 'Update Project facets';
147
- SQL
148
- end
149
- end
150
-
151
- A later version of this package may include generator macros to ease the task of defining new facet indices. However, this will
152
- have to wait until DataMapper can reliably transform expressions like Project.all(:field => 'science').status into a single SQL join query (currently it issues two queries in turn). Until then, the SQL expressions must be produced by hand.
153
-
154
- *In your model*
155
-
156
- = declaring facets:
157
-
158
- class Project
159
- is :faceted, :genre,
160
- :published => :nested, # default :logic for this facet
161
- :birthdate => :nested
162
- [ etc. ]
163
- end
164
-
165
- [ N.B. your facets don't have to be DataMapper properties! they can be any SQL computed value. this merely names the facets -
166
- definitions belong in a database migration. ]
167
-
168
- *In your controller*
169
-
170
- = to do a facet value count [ facet indices are used automatically where available ]
171
-
172
- Film.facet_count(:location, :genre => 'tragedy', :published => [2008, 11], :title.like => '%Death%', :order => [:location, :count.desc] )
173
-
174
- # provides facet to count, facet filter selections, a base query, and order for the facet value counts. you can also specify
175
- # :minimum, :offset, :limit, :type, and :nullable. see the specs for usage
176
-
177
- = to do a facet results query [ facet indices are used automatically where available ]
178
-
179
- Film.facet_results(:genre => 'tragedy', :published => [2008, 11], :title.like => '%Death%', :order => [:title, :author], :offset => 0, :limit => 20)
180
-
181
- # to alter the way that a facet is refined, provide :logic (options are :or, :and, :nested; default is :and)
182
- Film.facet_results(:genre => ['tragedy', 'comedy'], :published => [2008, 11],
183
- :logic => { :genre => :or, :published => :nested })
184
-
185
-
186
- ===== Merb extensions =====
187
-
188
- in controller...
189
-
190
- def counts(facet, search, filter={})
191
- provides :js
192
- counts = Project.facet_count(facet, :refinements => filter, :conditions => ["_fulltext @@ to_tsquery(?)", search])
193
- display counts
194
- end
195
-
196
- def results(search, filter={})
197
- provides :html
198
- results = Project.facet_result(:refinements => filter, :conditions => ["_fulltext @@ to_tsquery(?)", search])
199
- display results
200
- end
201
-
202
- in routes...
203
-
204
- match('/:controller/counts/:facet').to(:action => 'counts')
205
- match('/:controller/results').to(:action => 'results')
206
-
207
- in view.... (index.html.erb): (make sure to load rep.faceting.js in your header)
208
-
209
- <script language='javascript'>
210
- $().ready(function() {
211
- $('#plays').facet_context();
212
- $('.facet').facet();
213
- $('.nested_facet').nested_facet();
214
- $('#results').results();
215
- });
216
- </script>
217
- ...
218
- <div id='plays'>
219
- <div id='genre' class='facet'></div>
220
- <div id='published' class='nested_facet'></div>
221
- <div id='results' class='facet'></div>
222
- </div>
223
-
224
- The facet count data is served via JSON from the URL defined by the routes and method signatures above. The webservice URL
225
- is derived from the element ids (e.g. '/plays/counts/genre' above), or set via the 'url' option.
226
-
227
- For a complete description of how to use the ajax widgets, their options, and how to write new widgets that extend the base
228
- functionality, see the in-line documentation in rep.faceting.js and its associated FAQ.
229
-
230
-
231
129
  ===== PostgreSQL extensions =====
232
130
 
233
131
  = The following code leads you through an example of the SQL calls to set up and execute
data/TODO CHANGED
@@ -1,7 +1,17 @@
1
1
  TODO
2
2
 
3
+ - make rake tasks smarter about detecting whether to run NOT NECESSARY
4
+ - make rake tasks automatically choose task dep on db type NOT TO DO
5
+
6
+ - make sure example app can be set up and deployed via rake DONE
7
+ - fulltext indexing for citizens in migration
8
+
9
+ - facet index for citizens... migration or rake task?
10
+ - gender not getting generated right
11
+
3
12
  - README
4
- * recipe for running tests
13
+ * recipe for running tests DONE
14
+ * deployment
5
15
  * recipe for adding facets to new app DONE
6
16
  * declaring facets DONE
7
17
  * faceting db api DONE
@@ -21,7 +31,6 @@ TODO
21
31
  - get rid of annoying load warnings on test KNOWN ISSUE
22
32
  - cannot refine on null values in facets KNOWN ISSUE
23
33
 
24
-
25
34
  - integration with postgresql crontab
26
35
  - push compiled gems to gemcutter DONE (EXCEPT FACETING)
27
36
 
data/ext/README.signature CHANGED
@@ -25,8 +25,8 @@
25
25
  -- Installation
26
26
  --
27
27
  -- (1) gem install repertoire-faceting
28
- -- (2) rake faceting:postgres:install
29
- -- (3) rake faceting:postgres:load
28
+ -- (2) rake db:faceting:install
29
+ -- (3) rake db:faceting:load
30
30
  --
31
31
  -- The bitset PostgreSQL extension follows standards for C-language extensions:
32
32
  -- http://www.postgresql.org/docs/current/static/xfunc-c.html
data/ext/signature.sql.IN CHANGED
@@ -265,16 +265,20 @@ END;
265
265
  $$ LANGUAGE plpgsql;
266
266
 
267
267
 
268
- -- Utility function to measure how many elements in a loosely-packed id column are wasted
269
- -- returns a float between 0 (no waste) and 1.0 (all waste)
268
+ -- Utility function to measure how many bits from a loosely-packed id column would be wasted,
269
+ -- if they were all collected into a bitset signature. Returns a float between 0 (no waste)
270
+ -- and 1.0 (all waste).
270
271
  --
271
272
  CREATE OR REPLACE FUNCTION signature_wastage(tbl TEXT, col TEXT) RETURNS REAL AS $$
272
273
  DECLARE
273
- histogram signature;
274
+ max REAL;
275
+ count REAL;
274
276
  BEGIN
275
- EXECUTE 'SELECT signature(' || quote_ident(col) || ') FROM ' || quote_ident(tbl)
276
- INTO histogram;
277
- RETURN 1.0 - (count(histogram)::REAL / sig_length(histogram)::REAL);
277
+ EXECUTE 'SELECT count(*) FROM ' || quote_ident(tbl)
278
+ INTO count;
279
+ EXECUTE 'SELECT max(' || quote_ident(col) || ') FROM ' || quote_ident(tbl)
280
+ INTO max;
281
+ RETURN 1.0 - (count / (COALESCE(max, 0) + 1));
278
282
  END;
279
283
  $$ LANGUAGE plpgsql;
280
284
 
@@ -39,6 +39,18 @@ module Repertoire
39
39
  execute(sql)
40
40
  end
41
41
 
42
+ # Load PostgreSQL native bitset type into current database
43
+ def load_faceting
44
+ sql = File.read(Repertoire::Faceting::MODULE_PATH + '/ext/signature.sql')
45
+ unload_faceting
46
+ execute(sql)
47
+ end
48
+
49
+ # Unloads PostgreSQL native bitset type
50
+ def unload_faceting
51
+ execute("DROP TYPE IF EXISTS signature CASCADE")
52
+ end
53
+
42
54
  # Expands nested faceting for the specified table (once)
43
55
  def expand_nesting(table_name)
44
56
  sql = "SELECT expand_nesting('#{table_name}')"
@@ -76,6 +88,15 @@ module Repertoire
76
88
  "INNER JOIN members(#{exprs.join(' & ')}) AS _refinements_id ON (#{table_name}.#{faceting_id} = _refinements_id)"
77
89
  end
78
90
 
91
+ private
92
+
93
+ def ignoring_db_errors(&block)
94
+ begin
95
+ yield
96
+ rescue
97
+ end
98
+ end
99
+
79
100
  end
80
101
  end
81
102
  end
@@ -174,6 +174,7 @@ module Repertoire
174
174
 
175
175
  # re-create the facet indices
176
176
  facet_names.each do |name|
177
+ name = name.to_sym
177
178
  raise "Unknown facet #{name}" unless facet?(name)
178
179
  facets[name].create_index('_packed_id')
179
180
  end
@@ -193,8 +194,6 @@ module Repertoire
193
194
  connection.signature_wastage(table_name, col)
194
195
  end
195
196
 
196
-
197
-
198
197
  def should_unpack?
199
198
  (faceting_id == '_packed_id') && (signature_wastage('id') < 0.15)
200
199
  end
@@ -1,5 +1,5 @@
1
1
  require 'active_support/core_ext'
2
- require 'active_record/relation'
2
+ require 'active_record'
3
3
 
4
4
  module ActiveRecord #:nodoc: all
5
5
  class Relation
@@ -9,7 +9,8 @@ module Repertoire
9
9
 
10
10
  rake_tasks do
11
11
  dir = Pathname(__FILE__).dirname.expand_path
12
- load dir + "tasks.rake"
12
+ load dir + "tasks/all.rake"
13
+ load dir + "tasks/client.rake"
13
14
  end
14
15
 
15
16
  end
@@ -0,0 +1,12 @@
1
+ require 'pathname'
2
+
3
+ namespace :db do
4
+ namespace :faceting do
5
+
6
+ desc "Build and install PostgreSQL native bitset as shared library"
7
+ task :build do
8
+ system "cd #{Repertoire::Faceting::MODULE_PATH}/ext; make; sudo make install"
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require 'pathname'
2
+
3
+ namespace :db do
4
+ namespace :faceting do
5
+
6
+ desc "Load PostgreSQL native bitset type into current database"
7
+ task :load => :environment do
8
+ ActiveRecord::Base.connection.load_faceting
9
+ end
10
+
11
+ end
12
+ end
@@ -1,5 +1,5 @@
1
1
  module Repertoire
2
2
  module Faceting #:nodoc:
3
- VERSION = "0.5.1"
3
+ VERSION = "0.5.2"
4
4
  end
5
5
  end
@@ -5,6 +5,8 @@ require 'repertoire-assets'
5
5
  module Repertoire
6
6
  module Faceting
7
7
 
8
+ MODULE_PATH = File.expand_path('../../', __FILE__)
9
+
8
10
  module Relation
9
11
  autoload :SpawnMethods, 'repertoire-faceting/relation/spawn_methods'
10
12
  autoload :QueryMethods, 'repertoire-faceting/relation/query_methods'
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 5
8
- - 1
9
- version: 0.5.1
8
+ - 2
9
+ version: 0.5.2
10
10
  platform: ruby
11
11
  authors:
12
12
  - Christopher York
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-25 00:00:00 +01:00
17
+ date: 2010-10-28 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -124,7 +124,8 @@ files:
124
124
  - lib/repertoire-faceting/relation/query_methods.rb
125
125
  - lib/repertoire-faceting/relation/spawn_methods.rb
126
126
  - lib/repertoire-faceting/routing.rb
127
- - lib/repertoire-faceting/tasks.rake
127
+ - lib/repertoire-faceting/tasks/all.rake
128
+ - lib/repertoire-faceting/tasks/client.rake
128
129
  - lib/repertoire-faceting/version.rb
129
130
  - lib/repertoire-faceting.rb
130
131
  - public/images/repertoire-faceting/proportional_symbol.png
@@ -149,7 +150,7 @@ has_rdoc: true
149
150
  homepage: http://github.com/repertoire/repertoire-faceting
150
151
  licenses: []
151
152
 
152
- post_install_message: " ********************************************************************************\n If this is the first time you have installed Repertoire faceting, you need\n to build and install the native PostgreSQL extension:\n\n cd <my-rails-app>\n rake faceting:postgres:install\n\n See the repertoire-faceting README for details.\n ********************************************************************************\n"
153
+ post_install_message: " ********************************************************************************\n If this is the first time you have installed Repertoire faceting, you need\n to build and install the native PostgreSQL extension:\n\n cd <my-rails-app>\n rake db:faceting:build\n \n See the repertoire-faceting README for details.\n ********************************************************************************\n"
153
154
  rdoc_options: []
154
155
 
155
156
  require_paths:
@@ -1,29 +0,0 @@
1
- require 'pathname'
2
-
3
- namespace :faceting do
4
-
5
- namespace :postgres do
6
- dir = Pathname(__FILE__).dirname.expand_path + '../../ext'
7
-
8
- desc "Load bitset functions into a specific database"
9
- task :load => :install do
10
- puts "\nDatabase name?"
11
- db_name = $stdin.gets.chomp
12
- sharedir = `pg_config --sharedir`.chomp
13
- system "psql -Upostgres -f #{sharedir}/contrib/signature.sql #{db_name}"
14
- end
15
-
16
- desc "Build and install PostgreSQL native bitset type"
17
- task :install => :build do
18
- puts "Installing native extensions..."
19
- system "cd #{dir}; sudo make install"
20
- end
21
-
22
- task :build do
23
- puts "Building native extensions..."
24
- system "cd #{dir}; sudo make"
25
- end
26
-
27
- end
28
-
29
- end