marskal-search 0.2.4

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.
@@ -0,0 +1,35 @@
1
+
2
+ namespace :marskal_search do
3
+
4
+ desc 'Display Column Filter ShortCuts'
5
+ task :shortcuts do
6
+ spec = Gem::Specification.find_by_name("marskal-search")
7
+ doc_file = "#{spec.gem_dir}/supplimental_documentation/SHORTCUTS.md"
8
+
9
+ # puts doc_file
10
+
11
+ puts "\n\n"
12
+ dashed_line_length = 20 #defaulkt to 20 charcters long
13
+ l_file = File.open(doc_file, "r").each_line do |line|
14
+ if line == "---\n"
15
+ l_dashed_line = ''
16
+ dashed_line_length.times { l_dashed_line += '-'}
17
+ puts l_dashed_line
18
+ elsif line[0] == '#'
19
+ idx = line.index(' ')
20
+ puts line[idx..line.length].strip
21
+ elsif line == "```\n"
22
+ puts "\n"
23
+ next
24
+ elsif line[0..6].downcase == "back to"
25
+ next
26
+ else
27
+ puts line.gsub(/[\n`]/, '')
28
+ end
29
+ dashed_line_length = [dashed_line_length, line.length].max if line.strip.length > 0
30
+
31
+ end
32
+ l_file .close
33
+
34
+ end
35
+ end
Binary file
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'marskal/search/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "marskal-search"
8
+ spec.version = MarskalSearch::VERSION
9
+ spec.authors = ["Mike Urban"]
10
+ spec.email = ["mike@marskalgroup.com"]
11
+
12
+ spec.summary = %q{A Search Gem built for searching text strings in mysql}
13
+ spec.description = %q{This Ruby Rails gem allows a robust nested SQL text search. To date is has only been tested on MariaDB/MySQL.}
14
+ spec.homepage = "https://github.com/MarskalGroup/marskal-search"
15
+ spec.license = "MIT"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.10"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "rspec", "~> 3.3"
33
+ spec.add_development_dependency "activesupport", "~> 4.2"
34
+ spec.add_development_dependency "activerecord", "~> 4.2"
35
+ end
@@ -0,0 +1,180 @@
1
+ ### MarskalSearch Option List and Examples
2
+ ---
3
+ #### Usage
4
+ * This document contains a list of options for `class MarskalSearch` of the marskal-search gem.
5
+
6
+ ##### Class & Parameters #####
7
+ ```ruby
8
+ #
9
+ # Usage MarskalSearch.new (p_class, p_search_text, options)
10
+ #
11
+ # p_class: ActiveRecord Model
12
+ # examples: User Contact Book
13
+ # p_search: String to search for
14
+ # examples: "admin" "williams" "poe"
15
+ #
16
+ # options:
17
+ # **NOTE because of complicated queries, always include the table name with the field name for all parameters that allow fields.
18
+ # for example pass 'contacts.last_name' instead of just 'last_name'
19
+ # Also: this has only been tested for Mysql
20
+ # :select_columns => A List of columns to be selected
21
+ # **ex: "['contacts.last_name', 'contacts.first_name']"
22
+ # **joined table example: "['contacts.last_name', 'contacts.first_name', 'contact_phone_numbers.phone_number']"
23
+ # default: If blank, all fields will be selected from the primary table only unless otherwise changed by other options
24
+ # :not_distinct => Duplicates Allowed? Note this does not just look at any one field..it looks at the entire selected fieldset
25
+ # Default: false (no duplicates will be returned)
26
+ # :joins => Equivalent to the .joins option of an ActiveRecord relation. This parameters is simple passed on to that
27
+ # Example Single association ==> joins: :contact_phone_numbers
28
+ # Example Array association ==> joins: [:contact_phone_numbers, :contact_addresses, :contact_notes]
29
+ # IMPORTANT NOTE: These are LEFT JOINS, also These fields can be used in the select statement, the fields in these sub-tables will be searched unless excluded by other options
30
+ # Default: if blank, the no joins will be added. However, if join(s) is provided, the default will be to search all sub-table fields unless otherwise specified by other options
31
+ # :includes_for_select_and_search => Similar to :joins, except these are sql INNER JOINS
32
+ # IMPORTANT NOTE: These fields can be used in the select statement, the fields in these sub-tables will be searched unless excluded by other options
33
+ # Example Single association ==> includes_for_select_and_search: :contact_phone_numbers
34
+ # Example Array association ==> includes_for_select_and_search: [:contact_phone_numbers, :contact_addresses, :contact_notes]
35
+ # Default: if blank, no joins will be applied
36
+ # :includes_for_search_only => Similar to :joins, except these are sql LEFT OUTER JOINS and are only used for searching. If search_text is blank, this option is ignored
37
+ # IMPORTANT NOTE: These fields should NOT select statement, the fields in these sub-tables will be searched unless excluded by other options
38
+ # Example Single association ==> includes_for_search_only: :contact_phone_numbers
39
+ # Example Array association ==> includes_for_search_only: [:contact_phone_numbers, :contact_addresses, :contact_notes]
40
+ # Default: if blank, no joins will be applied
41
+ # :default_where => The where statement that will be applied in all cases. These are not excluded from counts.
42
+ # this is useful, when the entire set is actually just a subset of the overall data set
43
+ # for example: a database may have 1000's of contacts, but any particular user will only be allowed access to a subset of that data
44
+ # in this case the default_scope would be something like "user_id = 100"
45
+ # :where_string => This is simple an additional where clause to be added to the search
46
+ # Example: where_string: "contacts.contact_type = 'Investors'"
47
+ # Default: if blank, no additional conditions will be added
48
+ # :individual_column_filters => Used to apply search to an individual or columns
49
+ # This was originally developed to support column filters for jquery datatables, but can be used separately.
50
+ # It expects an array of hashes with as of now 3 values
51
+ # { name: name of db column
52
+ # operator: sql operator such as LIKE, =, IS NOT NULL IN, etc.
53
+ # value: what value are we searching for
54
+ # }
55
+ # IMPORTANT NOTE: if no operator is provided, it is assumed we are doing a LIKE '%value%' query
56
+ # See method self.prep_datatables_column_filter if you are using jquery datatables
57
+ # Example: [{ name: 'contacts.last_name', operator: '=', value: "'williams'"} => contacts.last_name = "williams" },
58
+ # { name: 'contacts.first_name', operator: 'IN', value: "('Wilma', 'Sam')"},
59
+ # { name: 'contacts.comments', value: "some note text"}
60
+ # ]
61
+ # For Datatables example:
62
+ # individual_column_filters: MarskalSearch.prep_datatables_column_filter(params)
63
+ # :search_only_these_data_types => Search only the datatypes specified
64
+ # Example: datatypes [:string, :text]
65
+ # Default: if blank, all data types will be searched unless excluded by other options
66
+ # :search_only_these_fields ==> used to limit the search to a particular field or fields. Very useful for a single column search, but can allow multiple as well
67
+ # Example Single Field: search_only_these_fields: "contacts.last_name"
68
+ # Example Multiple Fields: search_only_these_fields: ["contacts.last_name", "contacts.first_name_name", "contacts.company_name"]
69
+ # :do_not_search_these_fields => Exclude these specific fields from the search
70
+ # Example Single Field: do_not_search_these_fields: "contacts.salary"
71
+ # Example Multiple Fields: do_not_search_these_fields: ["contacts.salary", "contacts.birthday"]
72
+ # :ignore_default_search_field_exclusions => by default certain fields are excluded (such as id fields and rails timestamps) from the text search
73
+ # IF this is passed as true, these default excluded fields will NOT be excluded and will be searched
74
+ # Example: ignore_default_search_field_exclusions: true
75
+ # IMPORTANT NOTE: see the method default_field_excluded? for details on what fields get excluded from the search
76
+ # Default: false (meaning the special fields WILL be excluded from search)
77
+ # :case_sensitive ==> Determines whether the search is case sensitive
78
+ # IMPORTANT NOTE: This was tested, using the default setting for mysql which ignores case, so in this case the option has no value, but I left it in for other configurations
79
+ # Example: case_sensitive: true
80
+ # Default: true (case must match if your db is configured to allow case sensitivity )
81
+ # :order_string => This is simply the order string for the sql statement
82
+ # Example: order_string: order by "contacts.last_name, contacts.first_name"
83
+ # Default: if blank, no order will be added
84
+ # :offset ==> For larger queries we may want to get a chunk at a time, offset is the starting point for that chunk..to be used in conjunction with limit useful for pagination
85
+ # offset: 10 (start at the 11th record)
86
+ # offset: 0 (start at the 1st record)
87
+ # default: no offset is set, so search will start from beginning
88
+ # :limit ==> The maximum number of records to get..regardless of the amount of records that would be returned
89
+ # limit: 50 (retrive no more than 50 records)
90
+ # default: no limit, all records are retrieved
91
+ # IMPORTANT NOTE: :offset and :limit have no effect on the count and count_filtered methods, these methods will consider the entire data set
92
+ ```
93
+
94
+ ##### Examples: #####
95
+
96
+ ```ruby
97
+ def testme
98
+
99
+ # create User and Contact models with at least these fields
100
+ # User => id, last_name, first_name
101
+ # Contact => id, last_name, first_name, user_id
102
+ #
103
+ # The connect them in the models
104
+ # In User.rb => has_many :contacts
105
+ # In Contact.rb => belongs_to_user
106
+ #
107
+ # Populate some data and then you can experiment with these examples
108
+ #
109
+
110
+ #find where a user must have at least one contact, and 'mike' is found in either the users or the contacts table
111
+ #return the names from both tables and the user_id
112
+ #order by contacts last_name then first
113
+ #get the first 10 records
114
+ #Note 'new' cause the the creation not the execution, basically just prepares for other methods show further below
115
+ m = MarskalSearch.new(User, 'mike',
116
+ joins: :contacts,
117
+ select_columns: "users.last_name, users.first_name, users.id, contacts.last_name, contacts.first_name",
118
+ where_string: 'active = true',
119
+ order_string: 'contacts.last_name, contacts.first_name',
120
+ offset: 0,
121
+ limit: 10
122
+ )
123
+
124
+ #output method examples
125
+ m.count # how many records were found in search
126
+ m.count_without_search_text #apply the where_string if not blank, but exclude the search_text from count
127
+ m.count_all #how may records total without any filters or where clauses
128
+ m.to_sql #the sql statement as it will be passed to mysql or other sql client
129
+ m.results #execute query and return the results into an array of ActiveRecord Objects
130
+ m.results(format: :jqgrid) #execute query and return the results into a jqgrid friendly format
131
+ m.results(format: :datatables) #execute query and return the results into a juery datables friendly format
132
+ m.results(format: :marskal-api) #execute query and return the results into a marksal-api friendly output
133
+ m.pluck #execute query, but return the selected fields in a two dimensional array, just the values, not field names
134
+ m.complete_where_clause #just show me only the resulting qhere cluase based on current settings, (nothing is executed, display only)
135
+ m.combine_joins #show me the details of how the joins and includes options will be processed (nothing is executed, display only)
136
+
137
+
138
+ #find where a user MAY or MAY NOT have at least one contact, and 'mike' is found in either the users or the contacts table
139
+ #return the names from both tables and the user_id
140
+ #order by contacts last_name then first
141
+ #get the first 10 records
142
+
143
+ m1 = MarskalSearch.new(User, 'mike',
144
+ includes_for_select_and_search: :contacts,
145
+ select_columns: "users.last_name, users.first_name, users.id, contacts.last_name, contacts.first_name",
146
+ where_string: 'active = true',
147
+ order_string: 'contacts.last_name, contacts.first_name',
148
+ offset: 0,
149
+ limit: 10
150
+ )
151
+
152
+
153
+ #find where a user MAY or MAY NOT have at least one contact, and 'mike' is found in either the users or the contacts table
154
+ #return the names from ONLY the users table and the user id
155
+ #order by users last_name then first
156
+ #get the first 10 records
157
+ #NOTE this is basically like saying, give me all the users that have mike in the user record or the related detail records in contacts
158
+ # even if the contacts table has 100 mikes connected with user, only a single record would be returned for teh user
159
+ #nothing from the contact record is return..it is simply there for search needs
160
+
161
+ m2 = MarskalSearch.new(User, 'mike',
162
+ includes_for_search_only: :contacts,
163
+ select_columns: "users.last_name, users.first_name, users.id",
164
+ where_string: 'active = true',
165
+ order_string: 'users.last_name, users.first_name',
166
+ offset: 0,
167
+ limit: 10
168
+ )
169
+
170
+ #these can be daisy chained as well
171
+ MarskalSearch.new(User, 'mike', includes_for_search_only: :contacts).count
172
+ MarskalSearch.new(User, 'mike', includes_for_search_only: :contacts).results
173
+
174
+
175
+ end
176
+ ```
177
+
178
+
179
+ ---
180
+ Back to [README.md](../README.md)
@@ -0,0 +1,34 @@
1
+ ### List of column filter shortcuts for `MarskalSearch`
2
+ ---
3
+
4
+ #### Quick Reference
5
+
6
+ |Short Code | SQL | [`User Input`] | Gets all data where field...
7
+ |---------- | ------------- | ---------------- | ---------------------------------------
8
+ | % | LIKE | [`% 2015%`] | ..starts with `2015`
9
+ | | | [`% %Status`] | ..ends with `Status`
10
+ | | | [`% 17725`] | ..equal to 17725
11
+ | !% | NOT LIKE | [`!% 2015%`] | ..does not start with `2015`
12
+ | | | [`!% %Status`] | ..does not end with `Status`
13
+ | | | [`!% 17725`] | ..not equal to `17725`
14
+ | ~ | CONTAINS | [`~ approved`] | ..contains the word `approved`
15
+ | !~ | NOT CONTAINS | [`^ approved`] | ..does not contain the word `approved`
16
+ | ^ | IN | [`^ lst1,list3,lst5`] | ..is any of `lst1` or `lst3` or `lst5`
17
+ | | | [`^ 1,6,8`] | ..has a value of either `1` or `6` or `8`
18
+ | | | [`^ INTC,AAPL,PFE,GE`]| ..value of either `INTC` or `AAPL` or `PFE` or `GE`
19
+ | !^ | NOT IN | [`!^ lst1,list3,lst5`]| ..is anything except `lst1` and `lst3` and `lst5`
20
+ | | | [`!^ 1,6,8`] | ..has a value other than `1` or `6` or `8`
21
+ | | | [`!^ AA,GOOG,BA,F`] | ..anything but `AA` or `GOOG` or `BA` or `F`
22
+ | :: | BETWEEN | [`:: 1&&3`] | ..between the numbers of `1` AND `3`
23
+ | !:: | NOT BETWEEN | [`:: 1&&3`] | ..NOT between the numbers of `1` AND `3`
24
+ | > | > | [`> 4`] | ..greater than `4`
25
+ | \< | \< | [`< 4`] | ..less than `4`
26
+ | >= | >= | [`>= 4`] | ..greater than or equal to `4`
27
+ | \<= | \<= | [`<= 4`] | ..less than or equal to `4`
28
+ | = | = | [`= 4`] | ..equal to `4`
29
+ | != | != | [`!= 4`] | ..NOT equal to `4`
30
+
31
+
32
+ ---
33
+ Back to [README.md](../README.md)
34
+
@@ -0,0 +1,10 @@
1
+ # ToDo Items
2
+
3
+ * Add debug option via a config file maybe like devise does
4
+ * Test SqlServer
5
+ * Test SqlLite
6
+ * Test DataTables
7
+ * Used to work, but have not tested the latest versions
8
+
9
+ ---
10
+ Back to [README.md](../README.md)
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: marskal-search
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.4
5
+ platform: ruby
6
+ authors:
7
+ - Mike Urban
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-12-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activesupport
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '4.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '4.2'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activerecord
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.2'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.2'
83
+ description: This Ruby Rails gem allows a robust nested SQL text search. To date is
84
+ has only been tested on MariaDB/MySQL.
85
+ email:
86
+ - mike@marskalgroup.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".rspec"
93
+ - ".travis.yml"
94
+ - CHANGELOG.md
95
+ - Gemfile
96
+ - LICENSE.txt
97
+ - README.md
98
+ - Rakefile
99
+ - app/assets/javascripts/marskal-search.js
100
+ - app/controllers/marskal_search_controller.rb
101
+ - bin/console
102
+ - bin/setup
103
+ - config/routes.rb
104
+ - lib/marskal/search.rb
105
+ - lib/marskal/search/version.rb
106
+ - lib/marskal_search/marskal_active_record_extensions.rb
107
+ - lib/marskal_search/marskal_search.rb
108
+ - lib/tasks/filter_shortcuts.rake
109
+ - marskal-search-0.2.0.gem
110
+ - marskal-search.gemspec
111
+ - supplimental_documentation/DETAILED_README.md
112
+ - supplimental_documentation/SHORTCUTS.md
113
+ - supplimental_documentation/TODO.md
114
+ homepage: https://github.com/MarskalGroup/marskal-search
115
+ licenses:
116
+ - MIT
117
+ metadata:
118
+ allowed_push_host: https://rubygems.org
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 2.2.5
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: A Search Gem built for searching text strings in mysql
139
+ test_files: []