scope_by_fuzzy 0.0.2

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