keyword_search_yjchen 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 99b430cad0ca06c3aa0cd1b59d6cbbf0029ed61d
4
+ data.tar.gz: 85094d9cfaaa460182ee1ffef0b37b48e374b5df
5
+ SHA512:
6
+ metadata.gz: 4cd2225b2b5590ffaeff4148c2a0462c225cbfe1513eb9f1060f4dcf4ea8724f8e0374943e393ba47a02e9bcf38fb16394d765c32e231b0d80ac3af79f50319d
7
+ data.tar.gz: ddc756a7b1367faa4091959e32fdfedc7dbac81c650e4de3fc4cafb58020256729205e53ca6d35b702d0b7d728e906a75c4ecfc863f15be35a9e158ce89cd8a2
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ # Emacs
20
+ \#*
21
+ .\#*
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+
5
+ bundler_args: --without docs
6
+
7
+ notifications:
8
+ email:
9
+ - brwcodes@gmail.com
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in keyword_search.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2007-2013 Bruce Williams
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,8 @@
1
+ History.txt
2
+ lib/keyword_search/definition.rb
3
+ lib/keyword_search.rb
4
+ lib/keyword_search.rl
5
+ Manifest
6
+ Rakefile
7
+ README.rdoc
8
+ test/test_keyword_search.rb
data/README.md ADDED
@@ -0,0 +1,112 @@
1
+ Keyword Search
2
+ ==============
3
+
4
+ [![Build Status](https://travis-ci.org/bruce/keyword_search.png)](https://travis-ci.org/bruce/keyword_search)
5
+
6
+ Description
7
+ -----------
8
+
9
+ Generic library to parse GMail-style search strings for keyword/value pairs;
10
+ supports definition of valid keywords and handling of quoted values.
11
+
12
+ Requirements
13
+ ------------
14
+
15
+ None.
16
+
17
+ Features
18
+ --------
19
+
20
+ The library features a very simple, easy-to-use API.
21
+
22
+ * Define handlers for supported keywords with blocks
23
+ * Define the default keyword (values not part of a keyword/value pair)
24
+ * Handle negation
25
+
26
+ Please see the example provided below.
27
+
28
+ Synopsis
29
+ --------
30
+
31
+ Here's an example using ActiveRecord (though the library is generic, and can
32
+ be used for any Ruby project). The library isn't limited to search terms, as
33
+ shown in this example; how you use it is up to you.
34
+
35
+ First, let's build up some variables we'll be populating for a SQL query.
36
+
37
+ ```ruby
38
+ clauses = []
39
+ arguments = []
40
+ ```
41
+
42
+ Now let's set an example string to parse. Presumably you'd get this from
43
+ a form (ie, `params[:terms]`) or some other form of input.
44
+
45
+ ```ruby
46
+ terms = 'account has:attachment since:2006-12-03 -description:crazy'
47
+ ```
48
+
49
+ Now let's do the search, defining the handlers to deal with each keyword.
50
+
51
+ ```ruby
52
+ KeywordSearch.search(terms) do |with|
53
+
54
+ # This sets the keyword handler for bare words in the string,
55
+ # ie "account" in our example search terms
56
+ with.default_keyword :title
57
+
58
+ # Here's what we do when we encounter a "title" keyword
59
+ with.keyword :title do |values|
60
+ clauses << "title like ?"
61
+ arguments << "%#{values.join(' ')}%"
62
+ end
63
+
64
+ # For "has," we check the value provided (and only support "attachment")
65
+ with.keyword :has do |values|
66
+ clauses << 'has_attachment = true' if values.include?('attachment')
67
+ end
68
+
69
+ # Here we do some date parsing
70
+ with.keyword :since do |values|
71
+ date = Date.parse(values.first) # only support one
72
+ clauses << 'created_on >= ?'
73
+ arguments << date.to_s
74
+ end
75
+
76
+ # If a second parameter is defined for a block, you can handle negation.
77
+ # In this example, we don't want results whose description includes
78
+ # the word "crazy"
79
+ with.keyword :description do |values, positive|
80
+ clauses << "description #{'not' unless positive} like ?"
81
+ arguments << "%#{values.join(' ')}%"
82
+ end
83
+
84
+ end
85
+ ```
86
+
87
+ Immediately after the block is defined, the string is parsed and handlers
88
+ fire. Due to the magic of closures, we now have populated variables we can
89
+ use to build a real SQL query.
90
+
91
+ ```ruby
92
+ query = clauses.map { |c| "(#{c})" }.join(' AND ')
93
+ conditions = [query, *arguments]
94
+ results = Message.all(:conditions => conditions)
95
+ ```
96
+
97
+ Installation
98
+ ------------
99
+
100
+ ```
101
+ gem install keyword_search
102
+ ```
103
+
104
+ License
105
+ -------
106
+
107
+ See LICENSE.
108
+
109
+ Legal Notes
110
+ -----------
111
+
112
+ GMail is copyright Google, Inc.
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ desc "Run tests"
5
+ Rake::TestTask.new do |t|
6
+ t.pattern = 'test/test_*.rb'
7
+ t.verbose = true
8
+ t.warning = false # Ragel is noisy
9
+ end
10
+
11
+ task default: :test
12
+
13
+ desc "Build parser with Ragel"
14
+ task :ragel do
15
+ sh "ragel -R lib/keyword_search.rl -o lib/keyword_search.rb"
16
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ require 'keyword_search/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "keyword_search_yjchen"
9
+ spec.version = KeywordSearch::VERSION
10
+ spec.authors = ["Bruce Williams", "Eric Lindvall"]
11
+ spec.email = ["brwcodes@gmail.com", "eric@sevenscale.com"]
12
+ spec.summary = %q{Generic library to parse GMail-style search strings for keyword/value pairs; supports definition of valid keywords and handling of quoted values.}
13
+ spec.homepage = %q{http://github.com/bruce/keyword_search}
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.rdoc_options = ["--charset=UTF-8"]
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ end
@@ -0,0 +1,57 @@
1
+ module KeywordSearch
2
+
3
+ class Definition
4
+
5
+ class Keyword
6
+
7
+ attr_reader :name, :description, :handler
8
+ def initialize(name, description=nil, &handler)
9
+ @name, @description = name, description
10
+ @handler = handler
11
+ end
12
+
13
+ def handle(value, sign)
14
+ # If the handler is only expecting one argument,
15
+ # only give them the positive matches
16
+ if handler.arity == 1
17
+ handler.call(value) if sign
18
+ else
19
+ handler.call(value, sign)
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ def initialize
26
+ @default_keyword = nil
27
+ yield self if block_given?
28
+ end
29
+
30
+ def keywords
31
+ @keywords ||= []
32
+ end
33
+
34
+ def keyword(name, description=nil, &block)
35
+ keywords << Keyword.new(name, description, &block)
36
+ end
37
+
38
+ def default_keyword(name)
39
+ @default_keyword = name
40
+ end
41
+
42
+ def handle(key, values)
43
+ key = @default_keyword if key == :default
44
+ return false unless key
45
+ true_values, false_values = *values.partition { |v| v[1] }
46
+
47
+ # Get just the values
48
+ true_values.collect! { |v| v[0] }
49
+ false_values.collect! { |v| v[0] }
50
+
51
+ if k = keywords.detect { |kw| kw.name == key.to_sym}
52
+ k.handle(true_values, true) unless true_values.empty?
53
+ k.handle(false_values, false) unless false_values.empty?
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,3 @@
1
+ module KeywordSearch
2
+ VERSION = '1.5.0'
3
+ end