sequel-soft-deletes 0.1.2
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 +7 -0
- data/lib/sequel/plugins/soft_deletes.rb +121 -0
- data/spec/sequel/plugins/soft_deletes_spec.rb +242 -0
- data/spec/spec_helper.rb +25 -0
- metadata +186 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2b90ce7450ab370ffd9fb26653e35597ebd462bdaf660a4572a9b8ff63cfae9a
|
4
|
+
data.tar.gz: 6513ffde924e7dbfac20b26ad37aab7d1ebf08bf453c1adc279053984362334e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c6db370861d3c3430df66538c5c7270829c0c5a60c95f201436ce90b59272697e0d4cad07829b32fab1405ce9776b5428138272d17ebb1a1b77e8f86056a47fe
|
7
|
+
data.tar.gz: 0d5020c98215beb773b5f14fb781a15a78a5820294216622da6e701bb74a48c4e3eaf6510371579bc77c6a0b9f8d1ae0421b8c64fb495385e0de43eefeb1de51
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sequel"
|
4
|
+
require "sequel/model"
|
5
|
+
|
6
|
+
# Plugin for adding soft-delete to a model.
|
7
|
+
#
|
8
|
+
# == Example
|
9
|
+
#
|
10
|
+
# Defining a model class with a timestamp as the deletion flag:
|
11
|
+
#
|
12
|
+
# class ACME::Customer < Sequel::Model(:customers)
|
13
|
+
# plugin :soft_deletes, column: :deleted_at
|
14
|
+
#
|
15
|
+
# And in the schema:
|
16
|
+
# create_table( :customers ) do
|
17
|
+
# primary_key :id
|
18
|
+
# timestamptz :deleted_at
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
module Sequel::Plugins::SoftDeletes
|
22
|
+
VERSION = "0.1.2"
|
23
|
+
|
24
|
+
# Default plugin options
|
25
|
+
DEFAULT_OPTIONS = {
|
26
|
+
column: :soft_deleted_at,
|
27
|
+
omit_by_default: false,
|
28
|
+
}.freeze
|
29
|
+
|
30
|
+
def self.configure(model, opts=DEFAULT_OPTIONS)
|
31
|
+
opts = DEFAULT_OPTIONS.merge(opts)
|
32
|
+
column = opts[:column]
|
33
|
+
model.soft_delete_column = column
|
34
|
+
model.set_dataset(model.where(column => nil)) if opts[:omit_by_default]
|
35
|
+
end
|
36
|
+
|
37
|
+
module DatasetMethods
|
38
|
+
def soft_deleted
|
39
|
+
column = self.model.soft_delete_column
|
40
|
+
exclude(column => nil)
|
41
|
+
end
|
42
|
+
|
43
|
+
def not_soft_deleted
|
44
|
+
column = self.model.soft_delete_column
|
45
|
+
where(column => nil)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Methods to extend Model classes with.
|
50
|
+
module ClassMethods
|
51
|
+
##
|
52
|
+
# The Array of field which are images, as Symbols
|
53
|
+
attr_accessor :soft_delete_column
|
54
|
+
end
|
55
|
+
|
56
|
+
# Methods to extend Model instances with.
|
57
|
+
module InstanceMethods
|
58
|
+
### Returns +true+ if this object should be considered deleted.
|
59
|
+
def soft_deleted?
|
60
|
+
column = self.class.soft_delete_column
|
61
|
+
return self[column] ? true : false
|
62
|
+
end
|
63
|
+
|
64
|
+
alias is_soft_deleted? soft_deleted?
|
65
|
+
|
66
|
+
### Returns +true+ if the object is soft-deletable. By default, an
|
67
|
+
### object is soft-deletable if it has no +soft_deletion_blockers+.
|
68
|
+
def soft_deletable?
|
69
|
+
return self.soft_deletion_blockers.empty?
|
70
|
+
end
|
71
|
+
|
72
|
+
### Soft-delete this instance.
|
73
|
+
def soft_delete
|
74
|
+
column = self.class.soft_delete_column
|
75
|
+
|
76
|
+
self.db.transaction do
|
77
|
+
supered_from_around = false
|
78
|
+
self.around_soft_delete do
|
79
|
+
supered_from_around = true
|
80
|
+
raise_hook_failure(:before_soft_delete) unless self.before_soft_delete
|
81
|
+
|
82
|
+
self.update(column => Time.now)
|
83
|
+
|
84
|
+
self.after_soft_delete
|
85
|
+
end
|
86
|
+
raise_hook_failure(:around_soft_delete) unless supered_from_around
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
### Returns an array of conditions preventing soft-deletion. Default is an empty array.
|
91
|
+
def soft_deletion_blockers
|
92
|
+
return []
|
93
|
+
end
|
94
|
+
|
95
|
+
### Remove soft-deletion blockers. Default soft-deletion raises NotImplementedError.
|
96
|
+
def remove_soft_deletion_blockers
|
97
|
+
raise NotImplementedError
|
98
|
+
end
|
99
|
+
|
100
|
+
### Default 'before' soft-delete hook checks if object is soft-deletable.
|
101
|
+
### Aborts soft-deletion if it returns false.
|
102
|
+
def before_soft_delete
|
103
|
+
return self.soft_deletable?
|
104
|
+
end
|
105
|
+
|
106
|
+
### Default (empty) 'around' soft-delete model hook.
|
107
|
+
def around_soft_delete
|
108
|
+
yield
|
109
|
+
end
|
110
|
+
|
111
|
+
### Default (empty) 'after' soft-delete hook.
|
112
|
+
def after_soft_delete; end
|
113
|
+
|
114
|
+
### Return the information for the soft-deletes column.
|
115
|
+
def soft_delete_column
|
116
|
+
return self.class.schema.columns.find do |col|
|
117
|
+
col[:name] == self.class.soft_delete_column
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,242 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/integer/time"
|
4
|
+
require "sequel/plugins/soft_deletes"
|
5
|
+
require "sequel"
|
6
|
+
require "sqlite3"
|
7
|
+
|
8
|
+
RSpec.describe Sequel::Plugins::SoftDeletes, :db do
|
9
|
+
before(:each) do
|
10
|
+
@db = Sequel.sqlite
|
11
|
+
end
|
12
|
+
after(:each) do
|
13
|
+
@db.disconnect
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:table_name) { :soft_deletes_test }
|
17
|
+
|
18
|
+
it "sets the soft-delete column to :soft_deleted_at if none is specified" do
|
19
|
+
@db.create_table(:soft_deletes_test) do
|
20
|
+
primary_key :id
|
21
|
+
time :deleted_at
|
22
|
+
end
|
23
|
+
mc = Class.new(Sequel::Model(@db[:soft_deletes_test]))
|
24
|
+
mc.plugin(:soft_deletes)
|
25
|
+
expect(mc.soft_delete_column).to eq(:soft_deleted_at)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "allows the class to override the soft-delete column" do
|
29
|
+
@db.create_table(:soft_deletes_test) do
|
30
|
+
primary_key :id
|
31
|
+
time :deleted_at
|
32
|
+
end
|
33
|
+
mc = Class.new(Sequel::Model(@db[:soft_deletes_test]))
|
34
|
+
mc.plugin(:soft_deletes, column: :deleted_at)
|
35
|
+
expect(mc.soft_delete_column).to eq(:deleted_at)
|
36
|
+
end
|
37
|
+
|
38
|
+
it "defines a #soft_delete method on extended model instances" do
|
39
|
+
@db.create_table(:soft_deletes_test) do
|
40
|
+
primary_key :id
|
41
|
+
time :deleted_at
|
42
|
+
end
|
43
|
+
mc = Class.new(Sequel::Model(@db[:soft_deletes_test]))
|
44
|
+
mc.plugin(:soft_deletes)
|
45
|
+
@m = mc.new
|
46
|
+
|
47
|
+
expect(@m).to respond_to(:soft_delete)
|
48
|
+
end
|
49
|
+
|
50
|
+
context "extended model classes with a timestamp soft-delete column" do
|
51
|
+
before do
|
52
|
+
@db.create_table(:soft_deletes_test) do
|
53
|
+
primary_key :id
|
54
|
+
time :deleted_at
|
55
|
+
end
|
56
|
+
@c = Class.new(Sequel::Model(@db[:soft_deletes_test]))
|
57
|
+
@c.plugin(:soft_deletes, column: :deleted_at)
|
58
|
+
@m = @c.create
|
59
|
+
end
|
60
|
+
|
61
|
+
it "sets its column to 'now' when soft-deleted" do
|
62
|
+
@m.soft_delete
|
63
|
+
expect(@m.deleted_at).to be_a(Time)
|
64
|
+
expect(@m.deleted_at).to be_within(5.seconds).of(Time.now)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "sets up a subset for selecting (or de-selecting) soft-deleted rows" do
|
68
|
+
expect(@c.dataset.soft_deleted).to be_a(Sequel::Dataset)
|
69
|
+
expect(@c.dataset.not_soft_deleted).to be_a(Sequel::Dataset)
|
70
|
+
|
71
|
+
expect(@c.dataset.soft_deleted.all).not_to include(@m)
|
72
|
+
expect(@c.dataset.not_soft_deleted.all).to include(@m)
|
73
|
+
|
74
|
+
@m.soft_delete
|
75
|
+
expect(@c.dataset.soft_deleted.all).to include(@m)
|
76
|
+
expect(@c.dataset.not_soft_deleted.all).not_to include(@m)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "extended model classes with a 'before' soft-delete hook" do
|
81
|
+
before do
|
82
|
+
@db.create_table(:soft_deletes_test) do
|
83
|
+
primary_key :id
|
84
|
+
time :deleted_at
|
85
|
+
end
|
86
|
+
mc = Class.new(Sequel::Model(@db[:soft_deletes_test]))
|
87
|
+
mc.class_eval do
|
88
|
+
attr_accessor :hook_body
|
89
|
+
|
90
|
+
def before_soft_delete
|
91
|
+
self.hook_body.call
|
92
|
+
end
|
93
|
+
end
|
94
|
+
mc.plugin(:soft_deletes, column: :deleted_at)
|
95
|
+
@m = mc.new
|
96
|
+
end
|
97
|
+
|
98
|
+
it "has its hook called whenever an instance is soft-deleted" do
|
99
|
+
called = false
|
100
|
+
@m.hook_body = lambda do
|
101
|
+
called = true
|
102
|
+
end
|
103
|
+
@m.soft_delete
|
104
|
+
|
105
|
+
expect(@m).to be_is_soft_deleted
|
106
|
+
expect(called).to eq(true)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "is not soft-deleted if its hook returns false" do
|
110
|
+
@m.hook_body = lambda do
|
111
|
+
false
|
112
|
+
end
|
113
|
+
|
114
|
+
expect do
|
115
|
+
@m.soft_delete
|
116
|
+
end.to raise_error(Sequel::HookFailed, /before_soft_delete hook failed/i)
|
117
|
+
|
118
|
+
expect(@m).not_to be_soft_deleted
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context "extended model classes with an 'after' soft-delete hook" do
|
123
|
+
before do
|
124
|
+
@db.create_table(:soft_deletes_test) do
|
125
|
+
primary_key :id
|
126
|
+
time :deleted_at
|
127
|
+
end
|
128
|
+
mc = Class.new(Sequel::Model(@db[:soft_deletes_test]))
|
129
|
+
mc.class_eval do
|
130
|
+
attr_accessor :hook_body
|
131
|
+
|
132
|
+
def after_soft_delete
|
133
|
+
self.hook_body.call
|
134
|
+
end
|
135
|
+
end
|
136
|
+
mc.plugin(:soft_deletes, column: :deleted_at)
|
137
|
+
@m = mc.new
|
138
|
+
end
|
139
|
+
|
140
|
+
it "has its hook called whenever an instance is soft-deleted" do
|
141
|
+
called = false
|
142
|
+
@m.hook_body = lambda do
|
143
|
+
called = true
|
144
|
+
end
|
145
|
+
@m.soft_delete
|
146
|
+
|
147
|
+
expect(@m).to be_is_soft_deleted
|
148
|
+
expect(called).to eq(true)
|
149
|
+
end
|
150
|
+
|
151
|
+
it "is still soft-deleted even if its hook returns false" do
|
152
|
+
@m.hook_body = lambda do
|
153
|
+
false
|
154
|
+
end
|
155
|
+
|
156
|
+
expect { @m.soft_delete }.not_to raise_error
|
157
|
+
|
158
|
+
expect(@m).to be_is_soft_deleted
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "extended model classes with an 'around' soft-delete hook" do
|
163
|
+
before do
|
164
|
+
@db.create_table(:soft_deletes_test) do
|
165
|
+
primary_key :id
|
166
|
+
time :deleted_at
|
167
|
+
end
|
168
|
+
mc = Class.new(Sequel::Model(@db[:soft_deletes_test]))
|
169
|
+
mc.class_eval do
|
170
|
+
attr_accessor :hook_body
|
171
|
+
|
172
|
+
def around_soft_delete
|
173
|
+
super if self.hook_body.call
|
174
|
+
end
|
175
|
+
end
|
176
|
+
mc.plugin(:soft_deletes, column: :deleted_at)
|
177
|
+
@m = mc.new
|
178
|
+
end
|
179
|
+
|
180
|
+
it "has its hook called whenever an instance is soft-deleted" do
|
181
|
+
called = false
|
182
|
+
@m.hook_body = lambda do
|
183
|
+
called = true
|
184
|
+
end
|
185
|
+
@m.soft_delete
|
186
|
+
expect(@m).to be_is_soft_deleted
|
187
|
+
expect(called).to eq(true)
|
188
|
+
end
|
189
|
+
|
190
|
+
it "is not soft-deleted if its hook doesn't super" do
|
191
|
+
@m.hook_body = lambda do
|
192
|
+
false
|
193
|
+
end
|
194
|
+
|
195
|
+
expect do
|
196
|
+
@m.soft_delete
|
197
|
+
end.to raise_error(Sequel::HookFailed, /around_soft_delete hook failed/i)
|
198
|
+
|
199
|
+
expect(@m).not_to be_soft_deleted
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context "extended model classes with deletion blockers" do
|
204
|
+
before do
|
205
|
+
@db.create_table(:soft_deletes_test) do
|
206
|
+
primary_key :id
|
207
|
+
time :deleted_at
|
208
|
+
end
|
209
|
+
mc = Class.new(Sequel::Model(@db[:soft_deletes_test]))
|
210
|
+
mc.class_eval do
|
211
|
+
attr_reader :stub_soft_deletion_blockers
|
212
|
+
|
213
|
+
def initialize(*)
|
214
|
+
@stub_soft_deletion_blockers = []
|
215
|
+
super
|
216
|
+
end
|
217
|
+
|
218
|
+
def soft_deletion_blockers
|
219
|
+
return self.stub_soft_deletion_blockers
|
220
|
+
end
|
221
|
+
end
|
222
|
+
mc.plugin(:soft_deletes, column: :deleted_at)
|
223
|
+
@m = mc.new
|
224
|
+
end
|
225
|
+
|
226
|
+
it "is not soft-deleted if it has deletion blockers" do
|
227
|
+
@m.stub_soft_deletion_blockers << "A BLOCKER"
|
228
|
+
|
229
|
+
expect do
|
230
|
+
@m.soft_delete
|
231
|
+
end.to raise_error(Sequel::HookFailed, /before_soft_delete hook failed/i)
|
232
|
+
|
233
|
+
expect(@m).not_to be_soft_deleted
|
234
|
+
end
|
235
|
+
|
236
|
+
it "raises an error if remove_soft_deletion_blockers hasn't been implemented" do
|
237
|
+
expect do
|
238
|
+
@m.remove_soft_deletion_blockers
|
239
|
+
end.to raise_error(NotImplementedError)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "sequel/plugins/soft_deletes"
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
# config.full_backtrace = true
|
7
|
+
|
8
|
+
# RSpec::Support::ObjectFormatter.default_instance.max_formatted_output_length = 600
|
9
|
+
|
10
|
+
config.expect_with :rspec do |expectations|
|
11
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
12
|
+
end
|
13
|
+
|
14
|
+
config.mock_with :rspec do |mocks|
|
15
|
+
mocks.verify_partial_doubles = true
|
16
|
+
end
|
17
|
+
|
18
|
+
config.order = :random
|
19
|
+
Kernel.srand config.seed
|
20
|
+
|
21
|
+
config.filter_run :focus
|
22
|
+
config.run_all_when_everything_filtered = true
|
23
|
+
config.disable_monkey_patching!
|
24
|
+
config.default_formatter = "doc" if config.files_to_run.one?
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sequel-soft-deletes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Lithic Tech
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-04-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '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: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-performance
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop-rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop-sequel
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: sequel
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: sqlite3
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description:
|
154
|
+
email:
|
155
|
+
- hello@lithic.tech
|
156
|
+
executables: []
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- lib/sequel/plugins/soft_deletes.rb
|
161
|
+
- spec/sequel/plugins/soft_deletes_spec.rb
|
162
|
+
- spec/spec_helper.rb
|
163
|
+
homepage:
|
164
|
+
licenses:
|
165
|
+
- MIT
|
166
|
+
metadata: {}
|
167
|
+
post_install_message:
|
168
|
+
rdoc_options: []
|
169
|
+
require_paths:
|
170
|
+
- lib
|
171
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
172
|
+
requirements:
|
173
|
+
- - ">="
|
174
|
+
- !ruby/object:Gem::Version
|
175
|
+
version: 2.4.0
|
176
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
requirements: []
|
182
|
+
rubygems_version: 3.1.4
|
183
|
+
signing_key:
|
184
|
+
specification_version: 4
|
185
|
+
summary: Gem for enabling soft-deletion in tables
|
186
|
+
test_files: []
|