rokaki 0.9.0 → 0.11.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 +4 -4
- data/.github/workflows/codeql-analysis.yml +3 -3
- data/.github/workflows/spec.yml +69 -0
- data/Gemfile.lock +100 -52
- data/LICENSE.txt +1 -1
- data/README.md +26 -8
- data/lib/rokaki/filter_model/basic_filter.rb +43 -2
- data/lib/rokaki/filter_model/nested_filter.rb +46 -15
- data/lib/rokaki/filter_model/nested_like_filters.rb +42 -18
- data/lib/rokaki/filter_model.rb +112 -3
- data/lib/rokaki/version.rb +1 -1
- data/rokaki.gemspec +4 -0
- metadata +45 -3
- data/CODE_OF_CONDUCT.md +0 -74
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a8fb8c022307112af51183df513130d6ad467142320a4db9be178870583c2394
|
|
4
|
+
data.tar.gz: 611539f7d9500f30c5a847a89a7548119c14d4eac47761e9c08b5e706ae9f77c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3648caca4052f03440da996d1aed083c3ba9a29a5f14f06e9e9b2757d4d95f3356e793e22f1b1ebe0a149536a001367e6006d26d8521ce518885e32c36502130
|
|
7
|
+
data.tar.gz: ca064a797447597677bd5b2d2e00f6a2836bc5e69341990ac7da0742ccdc41383834f7a8c9bb6c4089a37e0293786c2536727b5c79d1dabf05a4c9df20f02b77
|
|
@@ -42,7 +42,7 @@ jobs:
|
|
|
42
42
|
|
|
43
43
|
# Initializes the CodeQL tools for scanning.
|
|
44
44
|
- name: Initialize CodeQL
|
|
45
|
-
uses: github/codeql-action/init@
|
|
45
|
+
uses: github/codeql-action/init@v3
|
|
46
46
|
with:
|
|
47
47
|
languages: ${{ matrix.language }}
|
|
48
48
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
@@ -53,7 +53,7 @@ jobs:
|
|
|
53
53
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
|
54
54
|
# If this step fails, then you should remove it and run the build manually (see below)
|
|
55
55
|
- name: Autobuild
|
|
56
|
-
uses: github/codeql-action/autobuild@
|
|
56
|
+
uses: github/codeql-action/autobuild@v3
|
|
57
57
|
|
|
58
58
|
# ℹ️ Command-line programs to run using the OS shell.
|
|
59
59
|
# 📚 https://git.io/JvXDl
|
|
@@ -67,4 +67,4 @@ jobs:
|
|
|
67
67
|
# make release
|
|
68
68
|
|
|
69
69
|
- name: Perform CodeQL Analysis
|
|
70
|
-
uses: github/codeql-action/analyze@
|
|
70
|
+
uses: github/codeql-action/analyze@v3
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
name: Run RSpec tests
|
|
2
|
+
on: [push]
|
|
3
|
+
jobs:
|
|
4
|
+
run-rspec-tests:
|
|
5
|
+
runs-on: ubuntu-latest
|
|
6
|
+
services:
|
|
7
|
+
mysql:
|
|
8
|
+
image: mysql:9.4
|
|
9
|
+
env:
|
|
10
|
+
MYSQL_DATABASE: rokaki
|
|
11
|
+
MYSQL_USER: rokaki
|
|
12
|
+
MYSQL_PASSWORD: rokaki
|
|
13
|
+
MYSQL_ROOT_PASSWORD: rokaki
|
|
14
|
+
ports:
|
|
15
|
+
- 3306:3306
|
|
16
|
+
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
|
17
|
+
|
|
18
|
+
postgres:
|
|
19
|
+
image: postgres:13
|
|
20
|
+
env:
|
|
21
|
+
POSTGRES_USER: postgres
|
|
22
|
+
POSTGRES_PASSWORD: "postgres"
|
|
23
|
+
POSTGRES_DB: rokaki
|
|
24
|
+
ports:
|
|
25
|
+
- 5432:5432
|
|
26
|
+
# needed because the postgres container does not provide a healthcheck
|
|
27
|
+
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
|
|
28
|
+
|
|
29
|
+
sqlserver:
|
|
30
|
+
image: mcr.microsoft.com/mssql/server:2022-latest
|
|
31
|
+
env:
|
|
32
|
+
ACCEPT_EULA: "Y"
|
|
33
|
+
MSSQL_SA_PASSWORD: "5QL5£rv£r"
|
|
34
|
+
ports:
|
|
35
|
+
- 1433:1433
|
|
36
|
+
# No built-in healthcheck; we'll wait in a step using nc
|
|
37
|
+
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v2
|
|
40
|
+
|
|
41
|
+
- name: Install system dependencies
|
|
42
|
+
run: |
|
|
43
|
+
sudo apt-get update
|
|
44
|
+
sudo apt-get install -y build-essential libpq-dev default-libmysqlclient-dev freetds-dev netcat-openbsd
|
|
45
|
+
|
|
46
|
+
- name: Set up Ruby
|
|
47
|
+
uses: ruby/setup-ruby@v1
|
|
48
|
+
with:
|
|
49
|
+
# Not needed with a .ruby-version file
|
|
50
|
+
ruby-version: 3.3.0
|
|
51
|
+
# runs 'bundle install' and caches installed gems automatically
|
|
52
|
+
bundler-cache: true
|
|
53
|
+
|
|
54
|
+
- name: Wait for databases to be ready
|
|
55
|
+
shell: bash
|
|
56
|
+
run: |
|
|
57
|
+
for i in {1..60}; do
|
|
58
|
+
nc -z 127.0.0.1 3306 && echo "MySQL up" && break || sleep 1
|
|
59
|
+
done
|
|
60
|
+
for i in {1..60}; do
|
|
61
|
+
nc -z 127.0.0.1 5432 && echo "Postgres up" && break || sleep 1
|
|
62
|
+
done
|
|
63
|
+
for i in {1..120}; do
|
|
64
|
+
nc -z 127.0.0.1 1433 && echo "SQL Server up" && break || sleep 1
|
|
65
|
+
done
|
|
66
|
+
|
|
67
|
+
- name: Run tests
|
|
68
|
+
run: |
|
|
69
|
+
./spec/ordered_run.sh
|
data/Gemfile.lock
CHANGED
|
@@ -1,50 +1,69 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
rokaki (0.
|
|
4
|
+
rokaki (0.11.0)
|
|
5
5
|
activesupport
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
activemodel (
|
|
11
|
-
activesupport (=
|
|
12
|
-
activerecord (
|
|
13
|
-
activemodel (=
|
|
14
|
-
activesupport (=
|
|
10
|
+
activemodel (8.0.3)
|
|
11
|
+
activesupport (= 8.0.3)
|
|
12
|
+
activerecord (8.0.3)
|
|
13
|
+
activemodel (= 8.0.3)
|
|
14
|
+
activesupport (= 8.0.3)
|
|
15
15
|
timeout (>= 0.4.0)
|
|
16
|
-
|
|
16
|
+
activerecord-sqlserver-adapter (8.0.9)
|
|
17
|
+
activerecord (~> 8.0.0)
|
|
18
|
+
tiny_tds
|
|
19
|
+
activesupport (8.0.3)
|
|
17
20
|
base64
|
|
21
|
+
benchmark (>= 0.3)
|
|
18
22
|
bigdecimal
|
|
19
|
-
concurrent-ruby (~> 1.0, >= 1.
|
|
23
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
20
24
|
connection_pool (>= 2.2.5)
|
|
21
25
|
drb
|
|
22
26
|
i18n (>= 1.6, < 2)
|
|
27
|
+
logger (>= 1.4.2)
|
|
23
28
|
minitest (>= 5.1)
|
|
24
|
-
|
|
25
|
-
tzinfo (~> 2.0)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
+
securerandom (>= 0.3)
|
|
30
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
31
|
+
uri (>= 0.13.1)
|
|
32
|
+
base64 (0.3.0)
|
|
33
|
+
benchmark (0.4.1)
|
|
34
|
+
bigdecimal (3.2.3)
|
|
35
|
+
byebug (12.0.0)
|
|
29
36
|
coderay (1.1.3)
|
|
30
|
-
concurrent-ruby (1.
|
|
31
|
-
connection_pool (2.4
|
|
32
|
-
database_cleaner-active_record (2.
|
|
37
|
+
concurrent-ruby (1.3.5)
|
|
38
|
+
connection_pool (2.5.4)
|
|
39
|
+
database_cleaner-active_record (2.2.2)
|
|
33
40
|
activerecord (>= 5.a)
|
|
34
|
-
database_cleaner-core (~> 2.0
|
|
41
|
+
database_cleaner-core (~> 2.0)
|
|
35
42
|
database_cleaner-core (2.0.1)
|
|
36
|
-
diff-lcs (1.
|
|
37
|
-
drb (2.2.
|
|
38
|
-
factory_bot (6.
|
|
39
|
-
activesupport (>=
|
|
40
|
-
ffi (1.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
diff-lcs (1.6.2)
|
|
44
|
+
drb (2.2.3)
|
|
45
|
+
factory_bot (6.5.5)
|
|
46
|
+
activesupport (>= 6.1.0)
|
|
47
|
+
ffi (1.17.2-aarch64-linux-gnu)
|
|
48
|
+
ffi (1.17.2-aarch64-linux-musl)
|
|
49
|
+
ffi (1.17.2-arm-linux-gnu)
|
|
50
|
+
ffi (1.17.2-arm-linux-musl)
|
|
51
|
+
ffi (1.17.2-arm64-darwin)
|
|
52
|
+
ffi (1.17.2-x86-linux-gnu)
|
|
53
|
+
ffi (1.17.2-x86-linux-musl)
|
|
54
|
+
ffi (1.17.2-x86_64-darwin)
|
|
55
|
+
ffi (1.17.2-x86_64-linux-gnu)
|
|
56
|
+
ffi (1.17.2-x86_64-linux-musl)
|
|
57
|
+
formatador (1.2.1)
|
|
58
|
+
reline
|
|
59
|
+
guard (2.19.1)
|
|
43
60
|
formatador (>= 0.2.4)
|
|
44
61
|
listen (>= 2.7, < 4.0)
|
|
62
|
+
logger (~> 1.6)
|
|
45
63
|
lumberjack (>= 1.0.12, < 2.0)
|
|
46
64
|
nenv (~> 0.1)
|
|
47
65
|
notiffany (~> 0.0)
|
|
66
|
+
ostruct (~> 0.6)
|
|
48
67
|
pry (>= 0.13.0)
|
|
49
68
|
shellany (~> 0.0)
|
|
50
69
|
thor (>= 0.18.1)
|
|
@@ -53,60 +72,85 @@ GEM
|
|
|
53
72
|
guard (~> 2.1)
|
|
54
73
|
guard-compat (~> 1.1)
|
|
55
74
|
rspec (>= 2.99.0, < 4.0)
|
|
56
|
-
i18n (1.14.
|
|
75
|
+
i18n (1.14.7)
|
|
57
76
|
concurrent-ruby (~> 1.0)
|
|
77
|
+
io-console (0.8.1)
|
|
58
78
|
listen (3.9.0)
|
|
59
79
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
|
60
80
|
rb-inotify (~> 0.9, >= 0.9.10)
|
|
61
|
-
|
|
81
|
+
logger (1.7.0)
|
|
82
|
+
lumberjack (1.4.2)
|
|
62
83
|
method_source (1.1.0)
|
|
63
|
-
minitest (5.
|
|
64
|
-
|
|
84
|
+
minitest (5.25.5)
|
|
85
|
+
mysql2 (0.5.7)
|
|
86
|
+
bigdecimal
|
|
65
87
|
nenv (0.3.0)
|
|
66
88
|
notiffany (0.1.3)
|
|
67
89
|
nenv (~> 0.1)
|
|
68
90
|
shellany (~> 0.0)
|
|
69
|
-
|
|
70
|
-
|
|
91
|
+
ostruct (0.6.3)
|
|
92
|
+
pg (1.6.2)
|
|
93
|
+
pg (1.6.2-aarch64-linux)
|
|
94
|
+
pg (1.6.2-aarch64-linux-musl)
|
|
95
|
+
pg (1.6.2-arm64-darwin)
|
|
96
|
+
pg (1.6.2-x86_64-darwin)
|
|
97
|
+
pg (1.6.2-x86_64-linux)
|
|
98
|
+
pg (1.6.2-x86_64-linux-musl)
|
|
99
|
+
pry (0.15.2)
|
|
71
100
|
coderay (~> 1.1)
|
|
72
101
|
method_source (~> 1.0)
|
|
73
|
-
pry-byebug (3.
|
|
74
|
-
byebug (~>
|
|
75
|
-
pry (>= 0.13, < 0.
|
|
76
|
-
rake (13.
|
|
102
|
+
pry-byebug (3.11.0)
|
|
103
|
+
byebug (~> 12.0)
|
|
104
|
+
pry (>= 0.13, < 0.16)
|
|
105
|
+
rake (13.3.0)
|
|
77
106
|
rb-fsevent (0.11.2)
|
|
78
|
-
rb-inotify (0.
|
|
107
|
+
rb-inotify (0.11.1)
|
|
79
108
|
ffi (~> 1.0)
|
|
80
|
-
|
|
109
|
+
reline (0.6.2)
|
|
110
|
+
io-console (~> 0.5)
|
|
111
|
+
rspec (3.13.1)
|
|
81
112
|
rspec-core (~> 3.13.0)
|
|
82
113
|
rspec-expectations (~> 3.13.0)
|
|
83
114
|
rspec-mocks (~> 3.13.0)
|
|
84
|
-
rspec-core (3.13.
|
|
115
|
+
rspec-core (3.13.5)
|
|
85
116
|
rspec-support (~> 3.13.0)
|
|
86
|
-
rspec-expectations (3.13.
|
|
117
|
+
rspec-expectations (3.13.5)
|
|
87
118
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
88
119
|
rspec-support (~> 3.13.0)
|
|
89
|
-
rspec-mocks (3.13.
|
|
120
|
+
rspec-mocks (3.13.5)
|
|
90
121
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
91
122
|
rspec-support (~> 3.13.0)
|
|
92
|
-
rspec-support (3.13.
|
|
123
|
+
rspec-support (3.13.6)
|
|
124
|
+
securerandom (0.4.1)
|
|
93
125
|
shellany (0.0.1)
|
|
94
|
-
sqlite3 (2.
|
|
95
|
-
sqlite3 (2.
|
|
96
|
-
sqlite3 (2.
|
|
97
|
-
sqlite3 (2.
|
|
98
|
-
sqlite3 (2.
|
|
99
|
-
sqlite3 (2.
|
|
100
|
-
sqlite3 (2.
|
|
101
|
-
sqlite3 (2.
|
|
102
|
-
sqlite3 (2.
|
|
103
|
-
sqlite3 (2.
|
|
104
|
-
thor (1.
|
|
105
|
-
timeout (0.4.
|
|
126
|
+
sqlite3 (2.7.4-aarch64-linux-gnu)
|
|
127
|
+
sqlite3 (2.7.4-aarch64-linux-musl)
|
|
128
|
+
sqlite3 (2.7.4-arm-linux-gnu)
|
|
129
|
+
sqlite3 (2.7.4-arm-linux-musl)
|
|
130
|
+
sqlite3 (2.7.4-arm64-darwin)
|
|
131
|
+
sqlite3 (2.7.4-x86-linux-gnu)
|
|
132
|
+
sqlite3 (2.7.4-x86-linux-musl)
|
|
133
|
+
sqlite3 (2.7.4-x86_64-darwin)
|
|
134
|
+
sqlite3 (2.7.4-x86_64-linux-gnu)
|
|
135
|
+
sqlite3 (2.7.4-x86_64-linux-musl)
|
|
136
|
+
thor (1.4.0)
|
|
137
|
+
timeout (0.4.3)
|
|
138
|
+
tiny_tds (3.3.0)
|
|
139
|
+
bigdecimal (~> 3)
|
|
140
|
+
tiny_tds (3.3.0-aarch64-linux-gnu)
|
|
141
|
+
bigdecimal (~> 3)
|
|
142
|
+
tiny_tds (3.3.0-aarch64-linux-musl)
|
|
143
|
+
bigdecimal (~> 3)
|
|
144
|
+
tiny_tds (3.3.0-x86_64-linux-gnu)
|
|
145
|
+
bigdecimal (~> 3)
|
|
146
|
+
tiny_tds (3.3.0-x86_64-linux-musl)
|
|
147
|
+
bigdecimal (~> 3)
|
|
106
148
|
tzinfo (2.0.6)
|
|
107
149
|
concurrent-ruby (~> 1.0)
|
|
150
|
+
uri (1.0.3)
|
|
108
151
|
|
|
109
152
|
PLATFORMS
|
|
153
|
+
aarch64-linux
|
|
110
154
|
aarch64-linux-gnu
|
|
111
155
|
aarch64-linux-musl
|
|
112
156
|
arm-linux-gnu
|
|
@@ -115,16 +159,19 @@ PLATFORMS
|
|
|
115
159
|
x86-linux-gnu
|
|
116
160
|
x86-linux-musl
|
|
117
161
|
x86_64-darwin
|
|
162
|
+
x86_64-linux
|
|
118
163
|
x86_64-linux-gnu
|
|
119
164
|
x86_64-linux-musl
|
|
120
165
|
|
|
121
166
|
DEPENDENCIES
|
|
122
167
|
activerecord
|
|
168
|
+
activerecord-sqlserver-adapter
|
|
123
169
|
bundler (~> 2.0)
|
|
124
170
|
database_cleaner-active_record
|
|
125
171
|
factory_bot
|
|
126
172
|
guard
|
|
127
173
|
guard-rspec
|
|
174
|
+
mysql2
|
|
128
175
|
pg
|
|
129
176
|
pry
|
|
130
177
|
pry-byebug
|
|
@@ -132,6 +179,7 @@ DEPENDENCIES
|
|
|
132
179
|
rokaki!
|
|
133
180
|
rspec (~> 3.0)
|
|
134
181
|
sqlite3
|
|
182
|
+
tiny_tds
|
|
135
183
|
|
|
136
184
|
BUNDLED WITH
|
|
137
185
|
2.5.3
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
# Rokaki
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/rokaki)
|
|
4
|
+
[](https://github.com/tevio/rokaki/actions/workflows/spec.yml)
|
|
4
5
|
|
|
5
|
-
This gem was
|
|
6
|
+
This gem was written to dry up filtering services in ActiveRecord based Rails apps or any plain Ruby app looking to implement "filters" or "faceted" search.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
The overall vision is to abstract away all of the lower level repetitive SQL and relational code to allow you to write model filters in a simple, relatively intuitive way, using ruby hashes and arrays mostly.
|
|
9
|
+
|
|
10
|
+
The DSL allows you to construct complex search models to filter results through without writing any SQL. I would recommend the reader to consult the specs in order to understand the features and syntax in detail, an intermediate understanding of Ruby and rspec TDD, and basic relational logic are recommended.
|
|
11
|
+
|
|
12
|
+
There are two modes of use, `Filterable` (designed for plain Ruby) and `FilterModel` (designed for Rails) that can be activated through the use of two mixins respectively, `include Rokaki::Filterable` or `include Rokaki::FilterModel`.
|
|
8
13
|
## Installation
|
|
9
14
|
|
|
10
15
|
Add this line to your application's Gemfile:
|
|
@@ -137,7 +142,7 @@ You can specify several configuration options, for example a `filter_key_prefix`
|
|
|
137
142
|
## `Rokaki::FilterModel` - Usage
|
|
138
143
|
|
|
139
144
|
### ActiveRecord
|
|
140
|
-
Include `Rokaki::FilterModel` in any ActiveRecord model (only AR >=
|
|
145
|
+
Include `Rokaki::FilterModel` in any ActiveRecord model (only AR >= 8.0.3 tested so far) you can generate the filter keys and the actual filter lookup code using the `filters` keyword on a model like so:-
|
|
141
146
|
|
|
142
147
|
```ruby
|
|
143
148
|
# Given the models
|
|
@@ -173,7 +178,7 @@ You can also filter collections of fields, simply pass an array of filter values
|
|
|
173
178
|
|
|
174
179
|
|
|
175
180
|
### Partial matching
|
|
176
|
-
You can use `like`
|
|
181
|
+
You can use `like` or the case insensitive `ilike` to perform a partial match on a specific field, there are 3 options:- `:prefix`, `:circumfix` and `:suffix`. There are two syntaxes you can use for this:-
|
|
177
182
|
|
|
178
183
|
#### 1. The `filter` command syntax
|
|
179
184
|
|
|
@@ -183,7 +188,7 @@ class ArticleFilter
|
|
|
183
188
|
include Rokaki::FilterModel
|
|
184
189
|
|
|
185
190
|
filter :article,
|
|
186
|
-
like: { # you can use ilike here instead if you
|
|
191
|
+
like: { # you can use ilike here instead if you want case insensitive results
|
|
187
192
|
author: {
|
|
188
193
|
first_name: :circumfix,
|
|
189
194
|
last_name: :circumfix
|
|
@@ -323,7 +328,7 @@ class ArticleFilter
|
|
|
323
328
|
|
|
324
329
|
filters :date, :title, author: [:first_name, :last_name]
|
|
325
330
|
like title: :circumfix
|
|
326
|
-
# ilike title: :circumfix # case insensitive
|
|
331
|
+
# ilike title: :circumfix # case insensitive mode
|
|
327
332
|
|
|
328
333
|
attr_accessor :filters
|
|
329
334
|
|
|
@@ -422,14 +427,27 @@ filterable.results
|
|
|
422
427
|
### Ruby setup
|
|
423
428
|
After checking out the repo, run `bin/setup` to install dependencies.
|
|
424
429
|
|
|
425
|
-
### Setting up the test
|
|
430
|
+
### Setting up the test databases
|
|
426
431
|
|
|
432
|
+
#### Postgres
|
|
427
433
|
```
|
|
428
434
|
docker pull postgres
|
|
429
435
|
docker run --name rokaki-postgres -e POSTGRES_USER=rokaki -e POSTGRES_PASSWORD=rokaki -d -p 5432:5432 postgres
|
|
430
436
|
```
|
|
431
437
|
|
|
432
|
-
|
|
438
|
+
#### Mysql
|
|
439
|
+
```
|
|
440
|
+
docker pull mysql
|
|
441
|
+
docker run --name rokaki-mysql -e MYSQL_ROOT_PASSWORD=rokaki -e MYSQL_PASSWORD=rokaki -e MYSQL_DATABASE=rokaki -e MYSQL_USER=rokaki -d -p 3306:3306 mysql:latest mysqld
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
### Specialised test runner
|
|
445
|
+
The test suite is designed to run against all supported database backends, since this can cause problems with timing and connection pools, the recommended way to run the tests is via a shell script.
|
|
446
|
+
|
|
447
|
+
From the rokaki root directory run: `./spec/ordered_run.sh`. This is the same script that runs on the Github CI here: [](https://github.com/tevio/rokaki/actions/workflows/spec.yml)
|
|
448
|
+
|
|
449
|
+
### Standard test runner (only recommended for development cycles)
|
|
450
|
+
You can still run `rake spec` to run the tests, there's no guarantee they will all pass due to race conditions from using multiple db backends (see above), but this mode is recommended for focusing on specific backends or tests during development (comment out what you don't want). You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
433
451
|
|
|
434
452
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
435
453
|
|
|
@@ -33,13 +33,37 @@ module Rokaki
|
|
|
33
33
|
@filter_template = "@model = #{prefix}filter_#{name} if #{filter};"
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
def case_sensitive
|
|
37
|
+
if db == :postgres
|
|
38
|
+
'LIKE'
|
|
39
|
+
elsif db == :mysql
|
|
40
|
+
'LIKE BINARY'
|
|
41
|
+
elsif db == :sqlserver
|
|
42
|
+
'LIKE'
|
|
43
|
+
else
|
|
44
|
+
'LIKE'
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def case_insensitive
|
|
49
|
+
if db == :postgres
|
|
50
|
+
'ILIKE'
|
|
51
|
+
elsif db == :mysql
|
|
52
|
+
'LIKE'
|
|
53
|
+
elsif db == :sqlserver
|
|
54
|
+
'LIKE'
|
|
55
|
+
else
|
|
56
|
+
'LIKE'
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
36
60
|
def _chain_filter_type(key)
|
|
37
61
|
filter = "#{prefix}#{key}"
|
|
38
62
|
query = ''
|
|
39
63
|
|
|
40
64
|
if like_semantics && mode = like_semantics[key]
|
|
41
65
|
query = build_like_query(
|
|
42
|
-
type:
|
|
66
|
+
type: case_sensitive,
|
|
43
67
|
query: query,
|
|
44
68
|
filter: filter,
|
|
45
69
|
mode: mode,
|
|
@@ -47,7 +71,7 @@ module Rokaki
|
|
|
47
71
|
)
|
|
48
72
|
elsif i_like_semantics && mode = i_like_semantics[key]
|
|
49
73
|
query = build_like_query(
|
|
50
|
-
type:
|
|
74
|
+
type: case_insensitive,
|
|
51
75
|
query: query,
|
|
52
76
|
filter: filter,
|
|
53
77
|
mode: mode,
|
|
@@ -60,10 +84,27 @@ module Rokaki
|
|
|
60
84
|
@filter_query = query
|
|
61
85
|
end
|
|
62
86
|
|
|
87
|
+
# # @model.where('`authors`.`first_name` LIKE BINARY :query', query: "%teev%").or(@model.where('`authors`.`first_name` LIKE BINARY :query', query: "%imi%"))
|
|
88
|
+
# if Array == filter
|
|
89
|
+
# first_term = filter.unshift
|
|
90
|
+
# query = "@model.where(\"#{key} #{type} ANY (ARRAY[?])\", "
|
|
91
|
+
# query += "prepare_terms(#{first_term}, :#{mode}))"
|
|
92
|
+
# filter.each { |term|
|
|
93
|
+
# query += ".or(@model.where(\"#{key} #{type} ANY (ARRAY[?])\", "
|
|
94
|
+
# query += "prepare_terms(#{first_term}, :#{mode})))"
|
|
95
|
+
# }
|
|
96
|
+
# else
|
|
97
|
+
# query = "@model.where(\"#{key.to_s.split(".").map { |item| "`#{item}`" }.join(".")} #{type.to_s.upcase} :query\", "
|
|
98
|
+
# query += "query: prepare_terms(#{filter}, \"#{type.to_s.upcase}\", :#{search_mode}))"
|
|
99
|
+
# end
|
|
100
|
+
|
|
63
101
|
def build_like_query(type:, query:, filter:, mode:, key:)
|
|
64
102
|
if db == :postgres
|
|
65
103
|
query = "@model.where(\"#{key} #{type} ANY (ARRAY[?])\", "
|
|
66
104
|
query += "prepare_terms(#{filter}, :#{mode}))"
|
|
105
|
+
elsif db == :sqlserver
|
|
106
|
+
# Delegate to helper that supports arrays and escaping with ESCAPE
|
|
107
|
+
query = "sqlserver_like(@model, \"#{key}\", \"#{type}\", #{filter}, :#{mode})"
|
|
67
108
|
else
|
|
68
109
|
query = "@model.where(\"#{key} #{type} :query\", "
|
|
69
110
|
query += "query: \"%\#{#{filter}}%\")" if mode == :circumfix
|
|
@@ -65,6 +65,30 @@ module Rokaki
|
|
|
65
65
|
current_like_key
|
|
66
66
|
end
|
|
67
67
|
|
|
68
|
+
def case_sensitive
|
|
69
|
+
if db == :postgres
|
|
70
|
+
'LIKE'
|
|
71
|
+
elsif db == :mysql
|
|
72
|
+
'LIKE BINARY'
|
|
73
|
+
elsif db == :sqlserver
|
|
74
|
+
'LIKE'
|
|
75
|
+
else
|
|
76
|
+
'LIKE'
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def case_insensitive
|
|
81
|
+
if db == :postgres
|
|
82
|
+
'ILIKE'
|
|
83
|
+
elsif db == :mysql
|
|
84
|
+
'LIKE'
|
|
85
|
+
elsif db == :sqlserver
|
|
86
|
+
'LIKE'
|
|
87
|
+
else
|
|
88
|
+
'LIKE'
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
68
92
|
def _build_deep_chain(keys)
|
|
69
93
|
name = ''
|
|
70
94
|
count = keys.size - 1
|
|
@@ -80,9 +104,9 @@ module Rokaki
|
|
|
80
104
|
leaf = nil
|
|
81
105
|
|
|
82
106
|
if search_mode = find_like_key(keys)
|
|
83
|
-
type =
|
|
107
|
+
type = case_sensitive
|
|
84
108
|
elsif search_mode = find_i_like_key(keys)
|
|
85
|
-
type =
|
|
109
|
+
type = case_insensitive
|
|
86
110
|
end
|
|
87
111
|
leaf = keys.pop
|
|
88
112
|
|
|
@@ -115,19 +139,27 @@ module Rokaki
|
|
|
115
139
|
where = where.join
|
|
116
140
|
|
|
117
141
|
if search_mode
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
search_mode: search_mode,
|
|
123
|
-
key: keys.last.to_s.pluralize,
|
|
124
|
-
leaf: leaf
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
@filter_methods << "def #{prefix}filter#{infix}#{name};"\
|
|
128
|
-
"@model.joins(#{joins}).#{query}; end;"
|
|
142
|
+
if db == :sqlserver
|
|
143
|
+
key_leaf = "#{keys.last.to_s.pluralize}.#{leaf}"
|
|
144
|
+
@filter_methods << "def #{prefix}filter#{infix}#{name};"\
|
|
145
|
+
"sqlserver_like(@model.joins(#{joins}), \"#{key_leaf}\", \"#{type}\", #{prefix}#{name}, :#{search_mode}); end;"
|
|
129
146
|
|
|
130
|
-
|
|
147
|
+
@filter_templates << "@model = #{prefix}filter#{infix}#{name} if #{prefix}#{name};"
|
|
148
|
+
else
|
|
149
|
+
query = build_like_query(
|
|
150
|
+
type: type,
|
|
151
|
+
query: '',
|
|
152
|
+
filter: "#{prefix}#{name}",
|
|
153
|
+
search_mode: search_mode,
|
|
154
|
+
key: keys.last.to_s.pluralize,
|
|
155
|
+
leaf: leaf
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
@filter_methods << "def #{prefix}filter#{infix}#{name};"\
|
|
159
|
+
"@model.joins(#{joins}).#{query}; end;"
|
|
160
|
+
|
|
161
|
+
@filter_templates << "@model = #{prefix}filter#{infix}#{name} if #{prefix}#{name};"
|
|
162
|
+
end
|
|
131
163
|
else
|
|
132
164
|
@filter_methods << "def #{prefix}filter#{infix}#{name};"\
|
|
133
165
|
"@model.joins(#{joins}).where(#{where}); end;"
|
|
@@ -144,7 +176,6 @@ module Rokaki
|
|
|
144
176
|
query = "where(\"#{key}.#{leaf} #{type} :query\", "
|
|
145
177
|
query += "query: \"%\#{#{filter}}%\")" if search_mode == :circumfix
|
|
146
178
|
query += "query: \"%\#{#{filter}}\")" if search_mode == :prefix
|
|
147
|
-
query += "query: \"\#{#{filter}}%\")" if search_mode == :suffix
|
|
148
179
|
end
|
|
149
180
|
|
|
150
181
|
query
|
|
@@ -194,22 +194,37 @@ module Rokaki
|
|
|
194
194
|
leaf = nil
|
|
195
195
|
leaf = keys.pop
|
|
196
196
|
|
|
197
|
+
# Compute key_leaf (qualified column) like other branches
|
|
198
|
+
key_leaf = keys.last ? "#{keys.last.to_s.pluralize}.#{leaf}" : leaf
|
|
199
|
+
|
|
200
|
+
if db == :sqlserver
|
|
201
|
+
# Build relation base with joins
|
|
202
|
+
if join_map.empty?
|
|
203
|
+
rel_expr = "@model"
|
|
204
|
+
elsif join_map.is_a?(Array)
|
|
205
|
+
rel_expr = "@model.joins(*#{join_map})"
|
|
206
|
+
else
|
|
207
|
+
rel_expr = "@model.joins(**#{join_map})"
|
|
208
|
+
end
|
|
197
209
|
|
|
198
|
-
|
|
199
|
-
type: type,
|
|
200
|
-
query: '',
|
|
201
|
-
filter: filter_name,
|
|
202
|
-
search_mode: search_mode,
|
|
203
|
-
key: keys.last,
|
|
204
|
-
leaf: leaf
|
|
205
|
-
)
|
|
206
|
-
|
|
207
|
-
if join_map.empty?
|
|
208
|
-
filter_query = "@model.#{query}"
|
|
209
|
-
elsif join_map.is_a?(Array)
|
|
210
|
-
filter_query = "@model.joins(*#{join_map}).#{query}"
|
|
210
|
+
filter_query = "sqlserver_like(#{rel_expr}, \"#{key_leaf}\", \"#{type.to_s.upcase}\", #{filter_name}, :#{search_mode})"
|
|
211
211
|
else
|
|
212
|
-
|
|
212
|
+
query = build_like_query(
|
|
213
|
+
type: type,
|
|
214
|
+
query: '',
|
|
215
|
+
filter: filter_name,
|
|
216
|
+
search_mode: search_mode,
|
|
217
|
+
key: keys.last,
|
|
218
|
+
leaf: leaf
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
if join_map.empty?
|
|
222
|
+
filter_query = "@model.#{query}"
|
|
223
|
+
elsif join_map.is_a?(Array)
|
|
224
|
+
filter_query = "@model.joins(*#{join_map}).#{query}"
|
|
225
|
+
else
|
|
226
|
+
filter_query = "@model.joins(**#{join_map}).#{query}"
|
|
227
|
+
end
|
|
213
228
|
end
|
|
214
229
|
|
|
215
230
|
if mode == or_key
|
|
@@ -225,11 +240,20 @@ module Rokaki
|
|
|
225
240
|
if db == :postgres
|
|
226
241
|
query = "where(\"#{key_leaf} #{type.to_s.upcase} ANY (ARRAY[?])\", "
|
|
227
242
|
query += "prepare_terms(#{filter}, :#{search_mode}))"
|
|
228
|
-
|
|
243
|
+
elsif db == :mysql
|
|
244
|
+
query = "where(\"#{key_leaf} #{type.to_s.upcase} :query\", "
|
|
245
|
+
query += "query: prepare_regex_terms(#{filter}, :#{search_mode}))"
|
|
246
|
+
else # :sqlserver and others
|
|
229
247
|
query = "where(\"#{key_leaf} #{type.to_s.upcase} :query\", "
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
248
|
+
if search_mode == :circumfix
|
|
249
|
+
query += "query: \"%\#{#{filter}}%\")"
|
|
250
|
+
elsif search_mode == :prefix
|
|
251
|
+
query += "query: \"%\#{#{filter}}\")"
|
|
252
|
+
elsif search_mode == :suffix
|
|
253
|
+
query += "query: \"\#{#{filter}}%\")"
|
|
254
|
+
else
|
|
255
|
+
query += "query: \"%\#{#{filter}}%\")"
|
|
256
|
+
end
|
|
233
257
|
end
|
|
234
258
|
|
|
235
259
|
query
|
data/lib/rokaki/filter_model.rb
CHANGED
|
@@ -19,6 +19,84 @@ module Rokaki
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
# Escape special LIKE characters in SQL Server patterns: %, _, [ and \\
|
|
23
|
+
def escape_like(term)
|
|
24
|
+
term.to_s.gsub(/[\\%_\[]/) { |m| "\\#{m}" }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Build LIKE patterns with proper prefix/suffix/circumfix and escaping for SQL Server
|
|
28
|
+
# Returns a String when param is scalar, or an Array of Strings when param is an Array
|
|
29
|
+
def prepare_like_terms(param, mode)
|
|
30
|
+
if Array === param
|
|
31
|
+
case mode
|
|
32
|
+
when :circumfix
|
|
33
|
+
param.map { |t| "%#{escape_like(t)}%" }
|
|
34
|
+
when :prefix
|
|
35
|
+
param.map { |t| "%#{escape_like(t)}" }
|
|
36
|
+
when :suffix
|
|
37
|
+
param.map { |t| "#{escape_like(t)}%" }
|
|
38
|
+
else
|
|
39
|
+
param.map { |t| "%#{escape_like(t)}%" }
|
|
40
|
+
end
|
|
41
|
+
else
|
|
42
|
+
case mode
|
|
43
|
+
when :circumfix
|
|
44
|
+
"%#{escape_like(param)}%"
|
|
45
|
+
when :prefix
|
|
46
|
+
"%#{escape_like(param)}"
|
|
47
|
+
when :suffix
|
|
48
|
+
"#{escape_like(param)}%"
|
|
49
|
+
else
|
|
50
|
+
"%#{escape_like(param)}%"
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Compose a SQL Server LIKE relation supporting arrays of terms (OR chained)
|
|
56
|
+
# column should be a fully qualified column expression, e.g., "authors.first_name" or "cs.title"
|
|
57
|
+
# type is usually "LIKE"
|
|
58
|
+
def sqlserver_like(model, column, type, value, mode)
|
|
59
|
+
terms = prepare_like_terms(value, mode)
|
|
60
|
+
if terms.is_a?(Array)
|
|
61
|
+
return model.none if terms.empty?
|
|
62
|
+
rel = model.where("#{column} #{type} :q0 ESCAPE '\\'", q0: terms[0])
|
|
63
|
+
terms[1..-1]&.each_with_index do |t, i|
|
|
64
|
+
rel = rel.or(model.where("#{column} #{type} :q#{i + 1} ESCAPE '\\'", "q#{i + 1}".to_sym => t))
|
|
65
|
+
end
|
|
66
|
+
rel
|
|
67
|
+
else
|
|
68
|
+
model.where("#{column} #{type} :q ESCAPE '\\'", q: terms)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def prepare_regex_terms(param, mode)
|
|
73
|
+
if Array === param
|
|
74
|
+
param_map = param.map { |term| ".*#{term}.*" } if mode == :circumfix
|
|
75
|
+
param_map = param.map { |term| ".*#{term}" } if mode == :prefix
|
|
76
|
+
param_map = param.map { |term| "#{term}.*" } if mode == :suffix
|
|
77
|
+
return param_map.join("|")
|
|
78
|
+
else
|
|
79
|
+
return [".*#{param}.*"] if mode == :circumfix
|
|
80
|
+
return [".*#{param}"] if mode == :prefix
|
|
81
|
+
return ["#{param}.*"] if mode == :suffix
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# "SELECT `articles`.* FROM `articles` INNER JOIN `authors` ON `authors`.`id` = `articles`.`author_id` WHERE (`authors`.`first_name` LIKE BINARY '%teev%' OR `authors`.`first_name` LIKE BINARY '%arv%')"
|
|
86
|
+
def prepare_or_terms(param, type, mode)
|
|
87
|
+
if Array === param
|
|
88
|
+
param_map = param.map { |term| "%#{term}%" } if mode == :circumfix
|
|
89
|
+
param_map = param.map { |term| "%#{term}" } if mode == :prefix
|
|
90
|
+
param_map = param.map { |term| "#{term}%" } if mode == :suffix
|
|
91
|
+
|
|
92
|
+
return param_map.join(" OR #{type} ")
|
|
93
|
+
else
|
|
94
|
+
return ["%#{param}%"] if mode == :circumfix
|
|
95
|
+
return ["%#{param}"] if mode == :prefix
|
|
96
|
+
return ["#{param}%"] if mode == :suffix
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
22
100
|
|
|
23
101
|
module ClassMethods
|
|
24
102
|
include Filterable::ClassMethods
|
|
@@ -143,17 +221,48 @@ module Rokaki
|
|
|
143
221
|
end
|
|
144
222
|
end
|
|
145
223
|
|
|
146
|
-
def
|
|
224
|
+
def filter_db(db)
|
|
225
|
+
@_filter_db = db
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def filter_model(model_class, db: nil)
|
|
229
|
+
@_filter_db = db if db
|
|
147
230
|
@model = (model_class.is_a?(Class) ? model_class : Object.const_get(model_class.capitalize))
|
|
148
231
|
class_eval "def set_model; @model ||= #{@model}; end;"
|
|
149
232
|
end
|
|
150
233
|
|
|
234
|
+
def case_sensitive
|
|
235
|
+
if @_filter_db == :postgres
|
|
236
|
+
'LIKE'
|
|
237
|
+
elsif @_filter_db == :mysql
|
|
238
|
+
# 'LIKE BINARY'
|
|
239
|
+
'REGEXP'
|
|
240
|
+
elsif @_filter_db == :sqlserver
|
|
241
|
+
'LIKE'
|
|
242
|
+
else
|
|
243
|
+
'LIKE'
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def case_insensitive
|
|
248
|
+
if @_filter_db == :postgres
|
|
249
|
+
'ILIKE'
|
|
250
|
+
elsif @_filter_db == :mysql
|
|
251
|
+
# 'LIKE'
|
|
252
|
+
'REGEXP'
|
|
253
|
+
elsif @_filter_db == :sqlserver
|
|
254
|
+
'LIKE'
|
|
255
|
+
else
|
|
256
|
+
'LIKE'
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
151
260
|
def like(args)
|
|
152
261
|
raise ArgumentError, 'argument mush be a hash' unless args.is_a? Hash
|
|
153
262
|
@_like_semantics = (@_like_semantics || {}).merge(args)
|
|
154
263
|
|
|
155
264
|
like_keys = LikeKeys.new(args)
|
|
156
|
-
like_filters(like_keys, term_type:
|
|
265
|
+
like_filters(like_keys, term_type: case_sensitive)
|
|
157
266
|
end
|
|
158
267
|
|
|
159
268
|
def ilike(args)
|
|
@@ -161,7 +270,7 @@ module Rokaki
|
|
|
161
270
|
@i_like_semantics = (@i_like_semantics || {}).merge(args)
|
|
162
271
|
|
|
163
272
|
like_keys = LikeKeys.new(args)
|
|
164
|
-
like_filters(like_keys, term_type:
|
|
273
|
+
like_filters(like_keys, term_type: case_insensitive)
|
|
165
274
|
end
|
|
166
275
|
|
|
167
276
|
# the model method is called to instatiate @model from the
|
data/lib/rokaki/version.rb
CHANGED
data/rokaki.gemspec
CHANGED
|
@@ -44,7 +44,11 @@ Gem::Specification.new do |spec|
|
|
|
44
44
|
spec.add_development_dependency 'factory_bot'
|
|
45
45
|
|
|
46
46
|
spec.add_development_dependency 'pg'
|
|
47
|
+
spec.add_development_dependency 'mysql2'
|
|
47
48
|
spec.add_development_dependency 'sqlite3'
|
|
48
49
|
spec.add_development_dependency 'database_cleaner-active_record'
|
|
50
|
+
# For SQL Server testing
|
|
51
|
+
spec.add_development_dependency 'tiny_tds'
|
|
52
|
+
spec.add_development_dependency 'activerecord-sqlserver-adapter'
|
|
49
53
|
|
|
50
54
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rokaki
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.11.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Steve Martin
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2025-10-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -164,6 +164,20 @@ dependencies:
|
|
|
164
164
|
- - ">="
|
|
165
165
|
- !ruby/object:Gem::Version
|
|
166
166
|
version: '0'
|
|
167
|
+
- !ruby/object:Gem::Dependency
|
|
168
|
+
name: mysql2
|
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
|
170
|
+
requirements:
|
|
171
|
+
- - ">="
|
|
172
|
+
- !ruby/object:Gem::Version
|
|
173
|
+
version: '0'
|
|
174
|
+
type: :development
|
|
175
|
+
prerelease: false
|
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
+
requirements:
|
|
178
|
+
- - ">="
|
|
179
|
+
- !ruby/object:Gem::Version
|
|
180
|
+
version: '0'
|
|
167
181
|
- !ruby/object:Gem::Dependency
|
|
168
182
|
name: sqlite3
|
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -192,6 +206,34 @@ dependencies:
|
|
|
192
206
|
- - ">="
|
|
193
207
|
- !ruby/object:Gem::Version
|
|
194
208
|
version: '0'
|
|
209
|
+
- !ruby/object:Gem::Dependency
|
|
210
|
+
name: tiny_tds
|
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
|
212
|
+
requirements:
|
|
213
|
+
- - ">="
|
|
214
|
+
- !ruby/object:Gem::Version
|
|
215
|
+
version: '0'
|
|
216
|
+
type: :development
|
|
217
|
+
prerelease: false
|
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
219
|
+
requirements:
|
|
220
|
+
- - ">="
|
|
221
|
+
- !ruby/object:Gem::Version
|
|
222
|
+
version: '0'
|
|
223
|
+
- !ruby/object:Gem::Dependency
|
|
224
|
+
name: activerecord-sqlserver-adapter
|
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
|
226
|
+
requirements:
|
|
227
|
+
- - ">="
|
|
228
|
+
- !ruby/object:Gem::Version
|
|
229
|
+
version: '0'
|
|
230
|
+
type: :development
|
|
231
|
+
prerelease: false
|
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
233
|
+
requirements:
|
|
234
|
+
- - ">="
|
|
235
|
+
- !ruby/object:Gem::Version
|
|
236
|
+
version: '0'
|
|
195
237
|
description: A dsl for filtering data in web requests
|
|
196
238
|
email:
|
|
197
239
|
- steve@martian.media
|
|
@@ -200,11 +242,11 @@ extensions: []
|
|
|
200
242
|
extra_rdoc_files: []
|
|
201
243
|
files:
|
|
202
244
|
- ".github/workflows/codeql-analysis.yml"
|
|
245
|
+
- ".github/workflows/spec.yml"
|
|
203
246
|
- ".gitignore"
|
|
204
247
|
- ".rspec"
|
|
205
248
|
- ".ruby-version"
|
|
206
249
|
- ".travis.yml"
|
|
207
|
-
- CODE_OF_CONDUCT.md
|
|
208
250
|
- Gemfile
|
|
209
251
|
- Gemfile.lock
|
|
210
252
|
- Guardfile
|
data/CODE_OF_CONDUCT.md
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
# Contributor Covenant Code of Conduct
|
|
2
|
-
|
|
3
|
-
## Our Pledge
|
|
4
|
-
|
|
5
|
-
In the interest of fostering an open and welcoming environment, we as
|
|
6
|
-
contributors and maintainers pledge to making participation in our project and
|
|
7
|
-
our community a harassment-free experience for everyone, regardless of age, body
|
|
8
|
-
size, disability, ethnicity, gender identity and expression, level of experience,
|
|
9
|
-
nationality, personal appearance, race, religion, or sexual identity and
|
|
10
|
-
orientation.
|
|
11
|
-
|
|
12
|
-
## Our Standards
|
|
13
|
-
|
|
14
|
-
Examples of behavior that contributes to creating a positive environment
|
|
15
|
-
include:
|
|
16
|
-
|
|
17
|
-
* Using welcoming and inclusive language
|
|
18
|
-
* Being respectful of differing viewpoints and experiences
|
|
19
|
-
* Gracefully accepting constructive criticism
|
|
20
|
-
* Focusing on what is best for the community
|
|
21
|
-
* Showing empathy towards other community members
|
|
22
|
-
|
|
23
|
-
Examples of unacceptable behavior by participants include:
|
|
24
|
-
|
|
25
|
-
* The use of sexualized language or imagery and unwelcome sexual attention or
|
|
26
|
-
advances
|
|
27
|
-
* Trolling, insulting/derogatory comments, and personal or political attacks
|
|
28
|
-
* Public or private harassment
|
|
29
|
-
* Publishing others' private information, such as a physical or electronic
|
|
30
|
-
address, without explicit permission
|
|
31
|
-
* Other conduct which could reasonably be considered inappropriate in a
|
|
32
|
-
professional setting
|
|
33
|
-
|
|
34
|
-
## Our Responsibilities
|
|
35
|
-
|
|
36
|
-
Project maintainers are responsible for clarifying the standards of acceptable
|
|
37
|
-
behavior and are expected to take appropriate and fair corrective action in
|
|
38
|
-
response to any instances of unacceptable behavior.
|
|
39
|
-
|
|
40
|
-
Project maintainers have the right and responsibility to remove, edit, or
|
|
41
|
-
reject comments, commits, code, wiki edits, issues, and other contributions
|
|
42
|
-
that are not aligned to this Code of Conduct, or to ban temporarily or
|
|
43
|
-
permanently any contributor for other behaviors that they deem inappropriate,
|
|
44
|
-
threatening, offensive, or harmful.
|
|
45
|
-
|
|
46
|
-
## Scope
|
|
47
|
-
|
|
48
|
-
This Code of Conduct applies both within project spaces and in public spaces
|
|
49
|
-
when an individual is representing the project or its community. Examples of
|
|
50
|
-
representing a project or community include using an official project e-mail
|
|
51
|
-
address, posting via an official social media account, or acting as an appointed
|
|
52
|
-
representative at an online or offline event. Representation of a project may be
|
|
53
|
-
further defined and clarified by project maintainers.
|
|
54
|
-
|
|
55
|
-
## Enforcement
|
|
56
|
-
|
|
57
|
-
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
58
|
-
reported by contacting the project team at steve@martian.media. All
|
|
59
|
-
complaints will be reviewed and investigated and will result in a response that
|
|
60
|
-
is deemed necessary and appropriate to the circumstances. The project team is
|
|
61
|
-
obligated to maintain confidentiality with regard to the reporter of an incident.
|
|
62
|
-
Further details of specific enforcement policies may be posted separately.
|
|
63
|
-
|
|
64
|
-
Project maintainers who do not follow or enforce the Code of Conduct in good
|
|
65
|
-
faith may face temporary or permanent repercussions as determined by other
|
|
66
|
-
members of the project's leadership.
|
|
67
|
-
|
|
68
|
-
## Attribution
|
|
69
|
-
|
|
70
|
-
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
|
71
|
-
available at [http://contributor-covenant.org/version/1/4][version]
|
|
72
|
-
|
|
73
|
-
[homepage]: http://contributor-covenant.org
|
|
74
|
-
[version]: http://contributor-covenant.org/version/1/4/
|