eyepiece 0.2.0 → 0.3.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '08654fe33f75242a2fd23359c80926349ee83aa9e5484eb98f6fce5039999e52'
4
- data.tar.gz: 65babcceac0433ca6b777ab1a81e3225cf659e74d3a34529b0becc6e0beabb8b
3
+ metadata.gz: 3de6b747ca261f9422fcb57f8f8fd68ab28a62a355a2ce76cfaee2f0722455b9
4
+ data.tar.gz: ff6e67ab38a25f74d6ad94cf80f6a97ba25177188a7fc6ccf80df583fa0a32a8
5
5
  SHA512:
6
- metadata.gz: a262903b867dbeab1be576b71b4cac255bd2445973f90b1ce10ac009cee64e7417d5a60022392c8e67a62a7980d2f8d32e3bd2959d5df3a2947aa13f364a0d8a
7
- data.tar.gz: be685e3fe2c9ad286217820062c01e6d7f2f6449b7b9b0eced86b4697505e0b98964173266e00f3f719b4af1830dc4826691f52c88e4e044950252b360036fc2
6
+ metadata.gz: 7b3aa77870677d4faf576211862e0a0f08804a1d94d36e15c30ad3056e6b5fb0899244ab6055cee6610f4ff8c1e1ddc9c2aeb2781c5b2317944bf50001a6f460
7
+ data.tar.gz: e6c4ec2e238f8a7cff904c43280e4c6883e8c8932926c459312df518d79e2a70fda740a78f9131f3ae5690375a0f1cd1b808041984765ef39fd4cbf2f6ca5117
data/CHANGELOG.md ADDED
@@ -0,0 +1,28 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [0.3.0] - 2026-04-09
8
+
9
+ ### Changed
10
+ - Rename `QuickSearch` to `Search` and `QuickBriefScope` to `Brief`
11
+ - Old names are preserved as backward-compatible aliases
12
+
13
+ ### Added
14
+ - `CHANGELOG.md` with `changelog_uri` in gemspec metadata
15
+
16
+ ## [0.2.0] - 2026-04-09
17
+
18
+ ### Changed
19
+ - Replace `ArgumentError` with custom `TooManyRecordsError`
20
+
21
+ ### Fixed
22
+ - Replace `IO.popen` with `Dir.glob` in gemspec and add ActiveRecord require
23
+
24
+ ## [0.1.0] - 2026-04-09
25
+
26
+ ### Added
27
+ - `QuickSearch` parameterized module for fast ILIKE searching on ActiveRecord models
28
+ - `QuickBriefScope` parameterized module for brief scope selection
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Eyepiece
4
+ class Brief < Module
5
+ def initialize(*fields, method: :brief)
6
+ @module = Module.new do
7
+ define_method method do
8
+ reselect(*fields)
9
+ end
10
+ end
11
+ end
12
+
13
+ def included(base)
14
+ base.send(:extend, @module)
15
+ end
16
+ end
17
+ end
@@ -1,17 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Eyepiece
4
- class QuickBriefScope < Module
5
- def initialize(*fields, method: :brief)
6
- @module = Module.new do
7
- define_method method do
8
- reselect(*fields)
9
- end
10
- end
11
- end
12
-
13
- def included(base)
14
- base.send(:extend, @module)
15
- end
16
- end
17
- end
3
+ require_relative "brief"
@@ -1,83 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Eyepiece
4
- class QuickSearch < Module
5
- class Searcher
6
- def self.call(...)
7
- new(...).call
8
- end
9
-
10
- def initialize(*fields, scope:, txt:, require_one:)
11
- self.scope = scope
12
- self.fields = fields
13
- self.txt = Array(txt)
14
- self.require_one = require_one
15
- end
16
-
17
- def call
18
- phrases =
19
- txt.map.with_index(1).to_h do |phrase, index|
20
- key = format("txt%<index>d", index: index).to_sym
21
- [key, "%#{phrase}%"]
22
- end
23
-
24
- records = scope.where(query, **phrases)
25
-
26
- if require_one
27
- raise_error(records.length) if records.length > 1
28
- records.first
29
- else
30
- records
31
- end
32
- end
33
-
34
- private
35
-
36
- def columns
37
- fields.map do |field|
38
- ActiveRecord::Base.connection.quote_column_name(field)
39
- end
40
- end
41
-
42
- def query
43
- queries =
44
- txt.flat_map.with_index(1) do |_, index|
45
- columns.map do |field|
46
- "#{field}::text ILIKE :txt#{index}"
47
- end
48
- end
49
-
50
- queries.join(" OR ")
51
- end
52
-
53
- def raise_error(count)
54
- raise(
55
- Eyepiece::TooManyRecordsError,
56
- format(
57
- "too many records (%<count>d) for \"%<query>s\"",
58
- count: count,
59
- query: txt.join(", "),
60
- ),
61
- )
62
- end
63
-
64
- attr_accessor :fields, :scope, :txt, :require_one
65
- end
66
-
67
- def included(base)
68
- base.send(:extend, @module)
69
- end
70
-
71
- def initialize(*fields)
72
- @module = Module.new do
73
- define_method :like do |*txt, require_one: true|
74
- Searcher.call(*fields, scope: self, txt: txt, require_one: require_one)
75
- end
76
-
77
- define_method :mlike do |*txt, require_one: false|
78
- Searcher.call(*fields, scope: self, txt: txt, require_one: require_one)
79
- end
80
- end
81
- end
82
- end
83
- end
3
+ require_relative "search"
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Eyepiece
4
+ class Search < Module
5
+ class Searcher
6
+ def self.call(...)
7
+ new(...).call
8
+ end
9
+
10
+ def initialize(*fields, scope:, txt:, require_one:)
11
+ self.scope = scope
12
+ self.fields = fields
13
+ self.txt = Array(txt)
14
+ self.require_one = require_one
15
+ end
16
+
17
+ def call
18
+ phrases =
19
+ txt.map.with_index(1).to_h do |phrase, index|
20
+ key = format("txt%<index>d", index: index).to_sym
21
+ [key, "%#{phrase}%"]
22
+ end
23
+
24
+ records = scope.where(query, **phrases)
25
+
26
+ if require_one
27
+ raise_error(records.length) if records.length > 1
28
+ records.first
29
+ else
30
+ records
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def columns
37
+ fields.map do |field|
38
+ ActiveRecord::Base.connection.quote_column_name(field)
39
+ end
40
+ end
41
+
42
+ def query
43
+ queries =
44
+ txt.flat_map.with_index(1) do |_, index|
45
+ columns.map do |field|
46
+ "#{field}::text ILIKE :txt#{index}"
47
+ end
48
+ end
49
+
50
+ queries.join(" OR ")
51
+ end
52
+
53
+ def raise_error(count)
54
+ raise(
55
+ Eyepiece::TooManyRecordsError,
56
+ format(
57
+ "too many records (%<count>d) for \"%<query>s\"",
58
+ count: count,
59
+ query: txt.join(", "),
60
+ ),
61
+ )
62
+ end
63
+
64
+ attr_accessor :fields, :scope, :txt, :require_one
65
+ end
66
+
67
+ def included(base)
68
+ base.send(:extend, @module)
69
+ end
70
+
71
+ def initialize(*fields)
72
+ @module = Module.new do
73
+ define_method :like do |*txt, require_one: true|
74
+ Searcher.call(*fields, scope: self, txt: txt, require_one: require_one)
75
+ end
76
+
77
+ define_method :mlike do |*txt, require_one: false|
78
+ Searcher.call(*fields, scope: self, txt: txt, require_one: require_one)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Eyepiece
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
data/lib/eyepiece.rb CHANGED
@@ -1,10 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "eyepiece/version"
4
- require_relative "eyepiece/quick_search"
5
- require_relative "eyepiece/quick_brief_scope"
4
+ require_relative "eyepiece/search"
5
+ require_relative "eyepiece/brief"
6
6
 
7
7
  module Eyepiece
8
8
  class Error < StandardError; end
9
9
  class TooManyRecordsError < Error; end
10
+
11
+ # Backward-compatible aliases
12
+ QuickSearch = Search
13
+ QuickBriefScope = Brief
10
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eyepiece
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Doe
@@ -31,9 +31,12 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - CHANGELOG.md
34
35
  - lib/eyepiece.rb
36
+ - lib/eyepiece/brief.rb
35
37
  - lib/eyepiece/quick_brief_scope.rb
36
38
  - lib/eyepiece/quick_search.rb
39
+ - lib/eyepiece/search.rb
37
40
  - lib/eyepiece/version.rb
38
41
  - sig/eyepiece.rbs
39
42
  homepage: https://github.com/example/eyepiece
@@ -42,6 +45,7 @@ licenses:
42
45
  metadata:
43
46
  homepage_uri: https://github.com/example/eyepiece
44
47
  source_code_uri: https://github.com/example/eyepiece
48
+ changelog_uri: https://github.com/example/eyepiece/blob/main/CHANGELOG.md
45
49
  rdoc_options: []
46
50
  require_paths:
47
51
  - lib
@@ -58,5 +62,5 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
62
  requirements: []
59
63
  rubygems_version: 3.6.9
60
64
  specification_version: 4
61
- summary: QuickSearch and QuickBriefScope for ActiveRecord models
65
+ summary: Search and Brief scope modules for ActiveRecord models
62
66
  test_files: []