scope_by_fuzzy 0.0.2

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.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Alejandro Juarez
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,44 @@
1
+ = Description
2
+
3
+ The scope_by_soundex gem provides a simple interface to use the set of functions of contrib/fuzzystringmatching for PostgreSQL.
4
+
5
+ == How to install It
6
+
7
+ Edit your Gemfile and insert the next line:
8
+
9
+ gem "scope_by_soundex"
10
+
11
+ Then use the bundler to install It:
12
+
13
+ $ bundle install
14
+
15
+ Then execute the rails migration generator:
16
+
17
+ $ ./script/rails generate scope_by_soundex_install
18
+
19
+ And finally run the rails migrations to add the functions for PostgreSQL:
20
+
21
+ $ rake db:migrate
22
+
23
+ == How to use It
24
+
25
+ # scope_by_soundex_matcher
26
+
27
+ class Person < ActiveRecord::Base
28
+ scope_by_soundex_matcher :find_by_fullname, :fields => [:firstname, :lastname]
29
+ end
30
+
31
+ Person.find_by_fullname 'Alejandro' => Returns a collection of active_record objects
32
+
33
+
34
+ # scope_by_difference_matcher
35
+
36
+ class Person < ActiveRecord::Base
37
+ scope_by_difference_matcher :find_by_fullname, :fields => [:firstname, :lastname]
38
+ end
39
+
40
+ Person.find_by_fullname 'Alejandro' => Returns a collection of active_record objects
41
+
42
+ == Copyright
43
+
44
+ Copyright (c) 2010 Alejandro Juarez. See LICENSE for details.
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'scope_by_fuzzy'
@@ -0,0 +1,3 @@
1
+ To copy the ScopeByFuzzy migration to your Rails App, just do:
2
+
3
+ rails generate scope_by_fuzzy
@@ -0,0 +1,18 @@
1
+ require 'rails/generators/migration'
2
+ class ScopeByFuzzyInstallGenerator < Rails::Generators::Base
3
+ include Rails::Generators::Migration
4
+
5
+ desc "Generates a migration file to add Fuzzy String Matching functions to your PostgreSQL database."
6
+
7
+ def self.source_root
8
+ @_source_root = File.expand_path('../templates', __FILE__)
9
+ end
10
+
11
+ def self.next_migration_number(path)
12
+ Time.now.utc.strftime("%Y%m%d%H%M%S")
13
+ end
14
+
15
+ def copy_migration_template
16
+ migration_template "migration.rb", "db/migrate/add_scope_by_fuzzy"
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ class AddScopeByFuzzy < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ execute "SET search_path = public;"
5
+
6
+ execute "CREATE OR REPLACE FUNCTION levenshtein (text,text) RETURNS int AS '$libdir/fuzzystrmatch','levenshtein' LANGUAGE C IMMUTABLE STRICT;"
7
+
8
+ execute "CREATE OR REPLACE FUNCTION levenshtein (text,text,int,int,int) RETURNS int AS '$libdir/fuzzystrmatch','levenshtein_with_costs' LANGUAGE C IMMUTABLE STRICT;"
9
+
10
+ execute "CREATE OR REPLACE FUNCTION metaphone (text,int) RETURNS text AS '$libdir/fuzzystrmatch','metaphone'LANGUAGE C IMMUTABLE STRICT;"
11
+
12
+ execute "CREATE OR REPLACE FUNCTION soundex(text) RETURNS text AS '$libdir/fuzzystrmatch', 'soundex' LANGUAGE C IMMUTABLE STRICT;"
13
+
14
+ execute "CREATE OR REPLACE FUNCTION text_soundex(text) RETURNS text AS '$libdir/fuzzystrmatch', 'soundex' LANGUAGE C IMMUTABLE STRICT;"
15
+
16
+ execute "CREATE OR REPLACE FUNCTION difference(text,text) RETURNS int AS '$libdir/fuzzystrmatch', 'difference' LANGUAGE C IMMUTABLE STRICT;"
17
+
18
+ execute "CREATE OR REPLACE FUNCTION dmetaphone (text) RETURNS text AS '$libdir/fuzzystrmatch', 'dmetaphone' LANGUAGE C IMMUTABLE STRICT;"
19
+
20
+ execute "CREATE OR REPLACE FUNCTION dmetaphone_alt (text) RETURNS text AS '$libdir/fuzzystrmatch', 'dmetaphone_alt' LANGUAGE C IMMUTABLE STRICT;"
21
+ end
22
+
23
+ def self.down
24
+ execute "SET search_path = public;"
25
+
26
+ execute "DROP FUNCTION dmetaphone_alt (text);"
27
+
28
+ execute "DROP FUNCTION dmetaphone (text);"
29
+
30
+ execute "DROP FUNCTION difference(text,text);"
31
+
32
+ execute "DROP FUNCTION text_soundex(text);"
33
+
34
+ execute "DROP FUNCTION soundex(text);"
35
+
36
+ execute "DROP FUNCTION metaphone (text,int);"
37
+
38
+ execute "DROP FUNCTION levenshtein (text,text,int,int,int);"
39
+
40
+ execute "DROP FUNCTION levenshtein (text,text);"
41
+ end
42
+ end
@@ -0,0 +1,12 @@
1
+ module ScopeByFuzzy
2
+ def enable_activerecord
3
+ return if ActiveRecord::Base.respond_to? :scope_by_soundex_matcher and ActiveRecord::Base.respond_to? :scope_by_difference_matcher
4
+ require 'scope_by_fuzzy/named_scope'
5
+ ::ActiveRecord::Base.send :include, ScopeByFuzzy::NamedScope
6
+ end
7
+ end
8
+
9
+ if defined? Rails
10
+ include ScopeByFuzzy
11
+ ScopeByFuzzy.enable_activerecord if defined? ActiveRecord
12
+ end
@@ -0,0 +1,46 @@
1
+ module ScopeByFuzzy
2
+ module NamedScope
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+
9
+ # scope_by_soundex
10
+ #
11
+ # Example:
12
+ # class Person < ActiveRecord::Base
13
+ # scope_by_soundex find_by_fullname, :fields => [:firstname, :lastname]
14
+ # end
15
+ # Person.find_by_fullname 'Alejandro'
16
+ def scope_by_soundex(method_name, options={})
17
+ sql = options[:fields].collect { |field| "soundex(#{field}) = soundex(:q)"}.join(' OR ')
18
+ scope method_name.to_sym, lambda {|string| where(sql, :q => string) }
19
+ end
20
+
21
+ # scope_by_difference
22
+ #
23
+ # Example:
24
+ # class Person < ActiveRecord::Base
25
+ # scope_by_difference find_by_fullname, :fields => [:firstname, :lastname]
26
+ # OR
27
+ # scope_by_difference find_by_fullname, :fields => [:firstname, :lastname], :position => 4, :operator => '>'
28
+ # OR
29
+ # scope_by_difference find_by_fullname, :by_sql => 'difference(firstname, :q) > 3 OR difference(:lastname, :q) > 4"
30
+ # end
31
+ # Person.find_by_fullname 'Alejandro'
32
+ def scope_by_difference(method_name, options={})
33
+ unless options.has_key? :by_sql
34
+ options[:position] ||= 3
35
+ options[:operator] = '>'
36
+ sql = options[:fields].collect { |field|"difference(#{field}, :q) #{options[:operator]} #{options[:position]}" }.join(' OR ')
37
+ else
38
+ sql = options[:by_sql]
39
+ end
40
+ scope method_name.to_sym, lambda {|string| where(sql, :q => string) }
41
+ end
42
+
43
+ # TODO: The following PostgreSQL functions are not implemented: dmetaphone_alt, dmetaphone, text_soundex, metaphone and levenshtein.
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,7 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "FuzzyStringMatcher" do
4
+ it "fails" do
5
+ fail "hey buddy, you should probably rename this file and start specing for real"
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'fuzzy_string_matcher'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scope_by_fuzzy
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Alejandro Juarez
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-10-01 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: The scope_by_fuzzy gem uses the set of functions of contrib/fuzzystringmatching for PostgreSQL.
23
+ email: alex@monsterlabs.com.mx
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - LICENSE
30
+ - README.rdoc
31
+ files:
32
+ - LICENSE
33
+ - init.rb
34
+ - lib/generators/scope_by_fuzzy_install/USAGE
35
+ - lib/generators/scope_by_fuzzy_install/scope_by_fuzzy_install_generator.rb
36
+ - lib/generators/scope_by_fuzzy_install/templates/migration.rb
37
+ - lib/scope_by_fuzzy.rb
38
+ - lib/scope_by_fuzzy/named_scope.rb
39
+ - README.rdoc
40
+ - spec/scope_by_fuzzy_spec.rb
41
+ - spec/spec_helper.rb
42
+ has_rdoc: true
43
+ homepage: http://github.com/monsterlabs/scope_by_fuzzy
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options:
48
+ - --charset=UTF-8
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.3.7
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: This gem provides the soundex and difference postgresql functions to determine similarities and distance between strings
76
+ test_files:
77
+ - spec/scope_by_fuzzy_spec.rb
78
+ - spec/spec_helper.rb