buscando_el_viento 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm ruby-1.8.7-p334@buscando_el_viento
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source "http://rubygems.org"
2
+
3
+ # migrations
4
+ gem 'activerecord', '3.1.0.rc1'
5
+
6
+ # specs
7
+ gem 'rake', '0.8.7'
8
+ gem 'rspec'
9
+
10
+ # nfi
11
+ gemspec
12
+
data/Gemfile.lock ADDED
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ buscando_el_viento (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activemodel (3.1.0.rc1)
10
+ activesupport (= 3.1.0.rc1)
11
+ bcrypt-ruby (~> 2.1.4)
12
+ builder (~> 3.0.0)
13
+ i18n (~> 0.6.0beta1)
14
+ activerecord (3.1.0.rc1)
15
+ activemodel (= 3.1.0.rc1)
16
+ activesupport (= 3.1.0.rc1)
17
+ arel (~> 2.1.1)
18
+ tzinfo (~> 0.3.27)
19
+ activesupport (3.1.0.rc1)
20
+ multi_json (~> 1.0)
21
+ arel (2.1.3)
22
+ bcrypt-ruby (2.1.4)
23
+ builder (3.0.0)
24
+ diff-lcs (1.1.2)
25
+ i18n (0.6.0)
26
+ multi_json (1.0.3)
27
+ rake (0.8.7)
28
+ rspec (2.6.0)
29
+ rspec-core (~> 2.6.0)
30
+ rspec-expectations (~> 2.6.0)
31
+ rspec-mocks (~> 2.6.0)
32
+ rspec-core (2.6.4)
33
+ rspec-expectations (2.6.0)
34
+ diff-lcs (~> 1.1.2)
35
+ rspec-mocks (2.6.0)
36
+ tzinfo (0.3.29)
37
+
38
+ PLATFORMS
39
+ ruby
40
+
41
+ DEPENDENCIES
42
+ activerecord (= 3.1.0.rc1)
43
+ buscando_el_viento!
44
+ rake (= 0.8.7)
45
+ rspec
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ # copied from RSpec :-p
5
+ require 'rspec'
6
+ require 'rspec/core'
7
+ require 'rspec/core/rake_task'
8
+ desc "Run all examples"
9
+ RSpec::Core::RakeTask.new(:spec) do |t|
10
+ t.rspec_path = 'rspec'
11
+ t.rspec_opts = %w[--color]
12
+ t.verbose = false
13
+ end
14
+
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "buscando_el_viento/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "buscando_el_viento"
7
+ s.version = BuscandoElViento::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["giles bowkett", "xavier shay"]
10
+ s.email = ["gilesb@gmail.com"]
11
+ s.homepage = "https://github.com/gilesbowkett/buscando_el_viento"
12
+ s.summary = s.description = %q{Rails migration class methods for PostgreSQL search}
13
+
14
+ s.rubyforge_project = "buscando_el_viento"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+ end
21
+
@@ -0,0 +1,12 @@
1
+ require 'active_record'
2
+ require 'active_record/base' # https://github.com/rails/rails/pull/1999
3
+
4
+ require File.dirname(__FILE__) + '/buscando_el_viento/vectors'
5
+ require File.dirname(__FILE__) + '/buscando_el_viento/triggers'
6
+ require File.dirname(__FILE__) + '/buscando_el_viento/indexes'
7
+ require File.dirname(__FILE__) + '/buscando_el_viento/search'
8
+
9
+ class BuscandoMigration < ActiveRecord::Migration
10
+ include BuscandoElViento
11
+ end
12
+
@@ -0,0 +1,26 @@
1
+ module BuscandoElViento
2
+ def index_name(table, column) # FIXME: better variable names
3
+ case column
4
+ when String, Symbol
5
+ "index_#{table}_on_#{column}_search_vector"
6
+ when Array
7
+ "index_#{table}_on_#{column.join("_and_")}_search_vector"
8
+ end
9
+ end
10
+
11
+ # yes, we're overwriting ActiveRecord::Migration's add_index, which, in this
12
+ # context, is less useful than it should be
13
+ def add_index(table, column)
14
+ execute <<-ADD_INDEX
15
+ CREATE INDEX #{index_name(table, column)}
16
+ ON #{table}
17
+ USING gin(search_vector);
18
+ ADD_INDEX
19
+ end
20
+
21
+ # remove_index gets the job done 9 times out of 10 for this stuff, but it
22
+ # needs a little assistance on composite indices
23
+ def remove_composite_index(table, columns)
24
+ remove_index table, vector_name(columns).to_s
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ module BuscandoElViento
2
+ def add_search(table, columns, options = {:fuzzy => false})
3
+ add_search_vector(table, columns)
4
+ add_trigger(table, columns, options)
5
+ add_index(table, columns)
6
+ end
7
+ def remove_search(table, columns)
8
+ remove_search_vector(table, columns)
9
+ remove_trigger(table, columns)
10
+ remove_index(table, columns)
11
+ end
12
+ end
@@ -0,0 +1,32 @@
1
+ module BuscandoElViento
2
+ def trigger_name(table, column)
3
+ "#{table}_#{vector_name(column)}_update"
4
+ end
5
+ def add_trigger(table, names, options = {:fuzzy => false})
6
+ dictionary = if options[:fuzzy]
7
+ "english"
8
+ else
9
+ "simple"
10
+ end
11
+
12
+ column = case names
13
+ when String, Symbol
14
+ names.to_s
15
+ when Array
16
+ names.join(", ")
17
+ end
18
+ execute <<TRIGGER
19
+ CREATE TRIGGER #{trigger_name(table, names)}
20
+ BEFORE INSERT OR UPDATE
21
+ ON #{table}
22
+ FOR EACH ROW EXECUTE PROCEDURE
23
+ tsvector_update_trigger(#{vector_name(names).to_s},
24
+ 'pg_catalog.#{dictionary}',
25
+ #{column});
26
+ TRIGGER
27
+ end
28
+ def remove_trigger(table, column)
29
+ execute "DROP TRIGGER IF EXISTS #{trigger_name(table, column)} on #{table};"
30
+ end
31
+ end
32
+
@@ -0,0 +1,17 @@
1
+ module BuscandoElViento
2
+ def vector_name(name)
3
+ case name
4
+ when String, Symbol
5
+ "#{name}_search_vector".to_sym
6
+ when Array
7
+ "#{name.join("_and_")}_search_vector".to_sym
8
+ end
9
+ end
10
+ def add_search_vector(table, column)
11
+ add_column(table, vector_name(column), "tsvector")
12
+ end
13
+ def remove_search_vector(table, column)
14
+ remove_column(table, vector_name(column))
15
+ end
16
+ end
17
+
@@ -0,0 +1,4 @@
1
+ module BuscandoElViento
2
+ VERSION = "0.0.1"
3
+ end
4
+
data/readme.md ADDED
@@ -0,0 +1,77 @@
1
+ buscando el viento
2
+ ==================
3
+
4
+ buscando el viento is a search migrations gem for PostgreSQL and Rails 3. It enables full-text searching by automating the process of creating appropriate migrations, and is largely based on Xavier Shay's PeepCode video on Postgres.
5
+
6
+ http://peepcode.com/products/postgresql
7
+
8
+ usage
9
+ -----
10
+
11
+ Inherit from `BuscandoMigration` instead of `ActiveRecord::Migration`. The `BuscandoElViento` version includes additional class methods. For example,
12
+
13
+ add_search_vector :users, :username
14
+
15
+ will add a search vector attribute to your `users` table, tracking the `username` attribute.
16
+
17
+ However if you do this
18
+
19
+ add_search :users, :username, :fuzzy => true
20
+
21
+ you get the search vector, a database trigger to keep that vector up to date, and an index to make retrieval fast.
22
+
23
+ Obviously the `:fuzzy` flag represents fuzzy versus exact search; this simply turns stemming on or off, although PostgreSQL supports a lot of additional features and options in its full-text search capacities. Use `remove_search` in the `down` method, to avoid `IrreversibleMigrations`. (Buscando doesn't support the `def change` approach yet, although there's no real reason why not.)
24
+
25
+ tests and specs
26
+ ---------------
27
+
28
+ In order to run your Rails tests, if you use PostgreSQL this way, you'll need to modify how Rails handles schema dumps. See the Postgres PeepCode for more info.
29
+
30
+ http://peepcode.com/products/postgresql
31
+
32
+ In terms of the gem's own specs, these could be better. They really just test the implementation, which is to say they verify that calling particular methods on the custom migration invokes particular other methods on the ActiveRecord migration.
33
+
34
+ This makes the specs fast, and I prefer tests and specs which circumvent the database in most circumstances, but if you're noodling around wondering what kind of patches a project this awesome could possibly need, I'd have a look at verifying that the specs actually result in code which can perform searches properly.
35
+
36
+ wtf? is that name spanish?
37
+ --------------------------
38
+
39
+ yes. "buscando el viento" means "seeking the wind" and gets its name from a line in a poem by Pablo Neruda.
40
+
41
+ mi voz buscaba el viento para tocar su oido
42
+
43
+ which means
44
+
45
+ my voice sought the wind to touch her hearing
46
+
47
+ (there's a nuance here: where in English, you say a person "plays" a musical instrument, in order to bring forth sound, in Spanish, you say a person "touches" a musical instrument.)
48
+
49
+ I chose the name because it annoys me how many APIs use `find` where what they really mean is `seek` or `look for`, and this made me think of how useful it is that Spanish has a commonly-used word which means `to look for something`. In English, we have `look for`, which is not really a word but an idiom, and incorporating prepositions into your code is difficult outside of Smalltalk; meanwhile, `seek` is great, but nobody in the United States seems to use it at all, unless they're hippies seeking for truth or sword-bearing elves seeking the Great Chalice Of Whatever The Fuck.
50
+
51
+ authors
52
+ -------
53
+
54
+ + Giles Bowkett
55
+ + Xavier Shay
56
+
57
+ license
58
+ -------
59
+
60
+ MIT License (which document included by reference)
61
+
62
+ hook a brother up
63
+ -----------------
64
+
65
+ Patches requested:
66
+
67
+ + `setweight()` support (**crucial**)
68
+ + Rails 3.1 generators, both to generate migrations and relevant model finders
69
+ + support for `def change` vs `def up` and `def down`
70
+ + better specs
71
+ + quite frankly, a better understanding of PostgreSQL would be useful
72
+
73
+ here be dragons
74
+ ---------------
75
+
76
+ This gem is still very early days status. May explode unexpectedly. Do not taunt Happy Fun Ball.
77
+
@@ -0,0 +1,11 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe BuscandoElViento do
4
+ it "exists" do
5
+ BuscandoElViento.class.should == Module
6
+ end
7
+ it "inherits" do
8
+ BuscandoMigration.new.should be_a(ActiveRecord::Migration)
9
+ end
10
+ end
11
+
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe BuscandoElViento do
4
+ before(:each) do
5
+ @search_migration = SearchMigration.new
6
+ end
7
+
8
+ # fuzzy search methods, in practice, only affect the definition of the DB trigger;
9
+ # however, I think requiring the downstream programmer to remember that kind of
10
+ # implementation detail somewhat defeats the purpose of a convenient API in the
11
+ # first place. BUT, since nobody's perfect, the search wrapper spec also contains a
12
+ # *tiny* bit of fuzzy-related whatnot.
13
+
14
+ it "enables fuzzy search" do
15
+ fuzzy_trigger = <<TRIGGER
16
+ CREATE TRIGGER posts_title_search_vector_update
17
+ BEFORE INSERT OR UPDATE
18
+ ON posts
19
+ FOR EACH ROW EXECUTE PROCEDURE
20
+ tsvector_update_trigger(title_search_vector,
21
+ 'pg_catalog.english',
22
+ title);
23
+ TRIGGER
24
+ @search_migration.should_receive(:execute).with(fuzzy_trigger)
25
+ @search_migration.add_trigger(:posts, :title, :fuzzy => true)
26
+ end
27
+ it "disables fuzzy search" do
28
+ exact_trigger = <<TRIGGER
29
+ CREATE TRIGGER posts_title_search_vector_update
30
+ BEFORE INSERT OR UPDATE
31
+ ON posts
32
+ FOR EACH ROW EXECUTE PROCEDURE
33
+ tsvector_update_trigger(title_search_vector,
34
+ 'pg_catalog.simple',
35
+ title);
36
+ TRIGGER
37
+ @search_migration.should_receive(:execute).with(exact_trigger)
38
+ @search_migration.add_trigger(:posts, :title, :fuzzy => false)
39
+ end
40
+ it "defaults to exact search" do
41
+ exact_trigger = <<TRIGGER
42
+ CREATE TRIGGER posts_title_search_vector_update
43
+ BEFORE INSERT OR UPDATE
44
+ ON posts
45
+ FOR EACH ROW EXECUTE PROCEDURE
46
+ tsvector_update_trigger(title_search_vector,
47
+ 'pg_catalog.simple',
48
+ title);
49
+ TRIGGER
50
+ @search_migration.should_receive(:execute).with(exact_trigger)
51
+ @search_migration.add_trigger(:posts, :title)
52
+ end
53
+ end
54
+
@@ -0,0 +1,68 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe BuscandoElViento do
4
+ before(:each) do
5
+ @search_migration = SearchMigration.new
6
+ end
7
+
8
+ it "names indexes" do
9
+ index_name = "index_users_on_username_search_vector"
10
+ @search_migration.index_name(:users, :username).should eq(index_name)
11
+ end
12
+ it "creates indexes" do
13
+ create_index = <<-CREATE_INDEX
14
+ CREATE INDEX index_users_on_username_search_vector
15
+ ON users
16
+ USING gin(search_vector);
17
+ CREATE_INDEX
18
+ @search_migration.should_receive(:execute).with(create_index)
19
+ @search_migration.add_index(:users, :username)
20
+ end
21
+
22
+ it "names composite indexes for searching multiple attributes" do
23
+ index_name = "index_posts_on_title_and_body_search_vector"
24
+ @search_migration.index_name(:posts, [:title, :body]).should eq(index_name)
25
+
26
+ index_name = "index_posts_on_title_and_body_and_topic_search_vector"
27
+ @search_migration.index_name(:posts, [:title, :body, :topic]).should eq(index_name)
28
+ end
29
+ it "creates composite indexes for searching multiple attributes" do
30
+ create_index = <<-CREATE_INDEX
31
+ CREATE INDEX index_posts_on_title_and_body_search_vector
32
+ ON posts
33
+ USING gin(search_vector);
34
+ CREATE_INDEX
35
+ @search_migration.should_receive(:execute).with(create_index)
36
+ @search_migration.add_index(:posts, [:title, :body])
37
+ end
38
+ it "removes composite indexes for searching multiple attributes" do
39
+ vector_name = "title_and_body_search_vector"
40
+ @search_migration.should_receive(:remove_index).with(:posts, vector_name)
41
+ @search_migration.remove_composite_index(:posts, [:title, :body])
42
+ end
43
+
44
+ # FIXME: spec cleanup...
45
+ # this last spec, and a few others like it, are maybe a little dumb. now that
46
+ # I think of it, I should probably just delete these. to create multiple
47
+ # distinct indices for searching distinct attributes, or to delete same, you
48
+ # just call add_index() or remove_index() as appropriate.
49
+
50
+ it "creates multiple indexes for searching distinct attributes" do
51
+ create_username_index = <<-CREATE_INDEX
52
+ CREATE INDEX index_users_on_username_search_vector
53
+ ON users
54
+ USING gin(search_vector);
55
+ CREATE_INDEX
56
+ @search_migration.should_receive(:execute).with(create_username_index)
57
+ @search_migration.add_index(:users, :username)
58
+
59
+ create_email_index = <<-CREATE_INDEX
60
+ CREATE INDEX index_users_on_email_search_vector
61
+ ON users
62
+ USING gin(search_vector);
63
+ CREATE_INDEX
64
+ @search_migration.should_receive(:execute).with(create_email_index)
65
+ @search_migration.add_index(:users, :email)
66
+ end
67
+ end
68
+
@@ -0,0 +1,5 @@
1
+ require File.expand_path("lib/buscando_el_viento")
2
+ %w{rubygems active_record}.each {|lib| require lib}
3
+
4
+ class SearchMigration < BuscandoMigration; end
5
+
@@ -0,0 +1,89 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe BuscandoElViento do
4
+ before(:each) do
5
+ @search_migration = SearchMigration.new
6
+ end
7
+
8
+ it "names triggers" do
9
+ @search_migration.trigger_name(:users, :username).should eq("users_username_search_vector_update")
10
+ end
11
+ it "creates triggers" do
12
+ @add_trigger = <<TRIGGER
13
+ CREATE TRIGGER users_username_search_vector_update
14
+ BEFORE INSERT OR UPDATE
15
+ ON users
16
+ FOR EACH ROW EXECUTE PROCEDURE
17
+ tsvector_update_trigger(username_search_vector,
18
+ 'pg_catalog.simple',
19
+ username);
20
+ TRIGGER
21
+ @search_migration.should_receive(:execute).with(@add_trigger)
22
+ @search_migration.add_trigger(:users, :username)
23
+ end
24
+
25
+ it "removes triggers" do
26
+ @drop_trigger = "DROP TRIGGER IF EXISTS users_username_search_vector_update on users;"
27
+ @search_migration.should_receive(:execute).with(@drop_trigger)
28
+ @search_migration.remove_trigger(:users, :username)
29
+ end
30
+
31
+ it "creates triggers for multiple distinct attributes, separately" do
32
+ @add_trigger = <<TRIGGER
33
+ CREATE TRIGGER users_username_search_vector_update
34
+ BEFORE INSERT OR UPDATE
35
+ ON users
36
+ FOR EACH ROW EXECUTE PROCEDURE
37
+ tsvector_update_trigger(username_search_vector,
38
+ 'pg_catalog.simple',
39
+ username);
40
+ TRIGGER
41
+ @search_migration.should_receive(:execute).with(@add_trigger)
42
+ @search_migration.add_trigger(:users, :username)
43
+ @add_trigger = <<TRIGGER
44
+ CREATE TRIGGER users_email_search_vector_update
45
+ BEFORE INSERT OR UPDATE
46
+ ON users
47
+ FOR EACH ROW EXECUTE PROCEDURE
48
+ tsvector_update_trigger(email_search_vector,
49
+ 'pg_catalog.simple',
50
+ email);
51
+ TRIGGER
52
+ @search_migration.should_receive(:execute).with(@add_trigger)
53
+ @search_migration.add_trigger(:users, :email)
54
+ end
55
+ it "removes triggers for multiple distinct attributes, separately" do
56
+ @username_drop_trigger = "DROP TRIGGER IF EXISTS users_username_search_vector_update on users;"
57
+ @email_drop_trigger = "DROP TRIGGER IF EXISTS users_email_search_vector_update on users;"
58
+
59
+ @search_migration.should_receive(:execute).with(@username_drop_trigger)
60
+ @search_migration.remove_trigger(:users, :username)
61
+
62
+ @search_migration.should_receive(:execute).with(@email_drop_trigger)
63
+ @search_migration.remove_trigger(:users, :email)
64
+ end
65
+
66
+ # multiple combined attributes, as one
67
+ it "names triggers with multiple combined attributes" do
68
+ attributes = [:title, :body]
69
+ trigger_name = "posts_title_and_body_search_vector_update"
70
+ @search_migration.trigger_name(:posts, attributes).should eq(trigger_name)
71
+ end
72
+ it "creates triggers for multiple combined attributes, as one" do
73
+ # FIXME: join these multi-line heredocs to eliminate indentation
74
+ # before executing, simply because getting the indentation
75
+ # right in the specs is an irritating waste of time
76
+ @add_trigger = <<TRIGGER
77
+ CREATE TRIGGER posts_title_and_body_search_vector_update
78
+ BEFORE INSERT OR UPDATE
79
+ ON posts
80
+ FOR EACH ROW EXECUTE PROCEDURE
81
+ tsvector_update_trigger(title_and_body_search_vector,
82
+ 'pg_catalog.simple',
83
+ title, body);
84
+ TRIGGER
85
+ @search_migration.should_receive(:execute).with(@add_trigger)
86
+ @search_migration.add_trigger(:posts, [:title, :body])
87
+ end
88
+ end
89
+
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe BuscandoElViento do
4
+ before(:each) do
5
+ @search_migration = SearchMigration.new
6
+ end
7
+
8
+ it "names vectors" do
9
+ @search_migration.vector_name(:username).should eq(:username_search_vector)
10
+ end
11
+ it "creates vector names for multiple combined attributes, as one" do
12
+ attributes = [:title, :description]
13
+ @search_migration.vector_name(attributes).should eq(:title_and_description_search_vector)
14
+ end
15
+ it "auto-adds search vectors" do
16
+ @search_migration.should_receive(:add_column).with(:users,
17
+ :username_search_vector,
18
+ "tsvector")
19
+ @search_migration.add_search_vector :users, :username
20
+ end
21
+ it "removes search vectors" do
22
+ @search_migration.should_receive(:remove_column).with(:users,
23
+ :username_search_vector)
24
+ @search_migration.remove_search_vector :users, :username
25
+ end
26
+ end
27
+
@@ -0,0 +1,31 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe BuscandoElViento do
4
+ before(:each) do
5
+ @search_migration = SearchMigration.new
6
+ end
7
+
8
+ it "adds search, defaulting to exact search" do
9
+ @search_migration.should_receive(:add_search_vector).with(:users, :username)
10
+ @search_migration.should_receive(:add_trigger).with(:users, :username, :fuzzy => false)
11
+ @search_migration.should_receive(:add_index).with(:users, :username)
12
+
13
+ @search_migration.add_search :users, :username
14
+ end
15
+ it "supports fuzzy search (stemming)" do
16
+ @search_migration.should_receive(:add_search_vector).with(:users, :username)
17
+ @search_migration.should_receive(:add_trigger).with(:users, :username, :fuzzy => true)
18
+ @search_migration.should_receive(:add_index).with(:users, :username)
19
+
20
+ @search_migration.add_search :users, :username, :fuzzy => true
21
+ end
22
+
23
+ it "removes search" do
24
+ @search_migration.should_receive(:remove_search_vector).with(:users, :username)
25
+ @search_migration.should_receive(:remove_trigger).with(:users, :username)
26
+ @search_migration.should_receive(:remove_index).with(:users, :username)
27
+
28
+ @search_migration.remove_search :users, :username
29
+ end
30
+ end
31
+
metadata ADDED
@@ -0,0 +1,91 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: buscando_el_viento
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - giles bowkett
14
+ - xavier shay
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-07-14 00:00:00 Z
20
+ dependencies: []
21
+
22
+ description: Rails migration class methods for PostgreSQL search
23
+ email:
24
+ - gilesb@gmail.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files: []
30
+
31
+ files:
32
+ - .rvmrc
33
+ - Gemfile
34
+ - Gemfile.lock
35
+ - Rakefile
36
+ - buscando_el_viento.gemspec
37
+ - lib/buscando_el_viento.rb
38
+ - lib/buscando_el_viento/indexes.rb
39
+ - lib/buscando_el_viento/search.rb
40
+ - lib/buscando_el_viento/triggers.rb
41
+ - lib/buscando_el_viento/vectors.rb
42
+ - lib/buscando_el_viento/version.rb
43
+ - readme.md
44
+ - spec/buscando_el_viento_spec.rb
45
+ - spec/fuzzy_spec.rb
46
+ - spec/indexes_spec.rb
47
+ - spec/spec_helper.rb
48
+ - spec/triggers_spec.rb
49
+ - spec/vectors_spec.rb
50
+ - spec/wrapper_spec.rb
51
+ homepage: https://github.com/gilesbowkett/buscando_el_viento
52
+ licenses: []
53
+
54
+ post_install_message:
55
+ rdoc_options: []
56
+
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ hash: 3
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ requirements: []
78
+
79
+ rubyforge_project: buscando_el_viento
80
+ rubygems_version: 1.8.3
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Rails migration class methods for PostgreSQL search
84
+ test_files:
85
+ - spec/buscando_el_viento_spec.rb
86
+ - spec/fuzzy_spec.rb
87
+ - spec/indexes_spec.rb
88
+ - spec/spec_helper.rb
89
+ - spec/triggers_spec.rb
90
+ - spec/vectors_spec.rb
91
+ - spec/wrapper_spec.rb