iry 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/rbi/iry.rbi DELETED
@@ -1,612 +0,0 @@
1
- # typed: strong
2
- # Entrypoint of constraint validation, include in a class inheriting {ActiveRecord::Base} and the following class-level
3
- # methods will be available:
4
- # - {Macros#constraints}
5
- # - {Macros#check_constraint}
6
- # - {Macros#exclusion_constraint}
7
- # - {Macros#foreign_key_constraint}
8
- # - {Macros#unique_constraint}
9
- #
10
- # @example User unique constraint validation
11
- # # The database schema has a unique constraint on email field
12
- # class User < ActiveRecord::Base
13
- # include Iry
14
- #
15
- # unique_constraint :email
16
- # end
17
- #
18
- # user = User.create!(email: "user@example.com")
19
- # fail_user = User.new(email: "user@example.com")
20
- # Iry.save(fail_user)
21
- # fail_user.errors.details.fetch(:email) #=> [{error: :taken}]
22
- module Iry
23
- VERSION = T.let(File.read(File.expand_path("../../VERSION", __dir__)).strip.freeze, T.untyped)
24
-
25
- # Inherited from {ActiveRecord::RecordInvalid}, returns the model for
26
- # which the constraint violations have been detected
27
- sig { returns(Handlers::Model) }
28
- def record; end
29
-
30
- # _@param_ `klass`
31
- sig { params(klass: Module).void }
32
- def self.included(klass); end
33
-
34
- # Executes block and in case of constraints violations on `model`, block is
35
- # halted and errors are appended to `model`
36
- #
37
- # _@param_ `model` — model object for which constraints should be monitored and for which errors should be added to
38
- #
39
- # _@return_ — the `model` or `nil` if a a constraint is
40
- # violated
41
- #
42
- # Handle constraints for unique user
43
- # ```ruby
44
- # # The database schema has a unique constraint on email field
45
- # class User < ActiveRecord::Base
46
- # include Iry
47
- #
48
- # unique_constraint :email
49
- # end
50
- #
51
- # user = User.create!(email: "user@example.com")
52
- # fail_user = User.new(email: "user@example.com")
53
- # result = Iry.handle_constraints(fail_user) { fail_user.save }
54
- # result #=> nil
55
- # fail_user.errors.details.fetch(:email) #=> [{error: :taken}]
56
- # ```
57
- sig { params(model: Handlers::Model, block: T.untyped).void }
58
- def self.handle_constraints(model, &block); end
59
-
60
- # Executes block and in case of constraints violations on `model`, block is
61
- # halted, errors are appended to `model` and {StatementInvalid} is raised
62
- #
63
- # _@param_ `model` — model object for which constraints should be monitored and for which errors should be added to
64
- #
65
- # _@return_ — returns `model` parameter
66
- sig { params(model: Handlers::Model, block: T.untyped).returns(Handlers::Model) }
67
- def self.handle_constraints!(model, &block); end
68
-
69
- # Similar to {ActiveRecord::Base#save} but in case of constraint violations,
70
- # `false` is returned and `errors` are populated.
71
- # Aside from `model`, it takes the same arguments as
72
- # {ActiveRecord::Base#save}
73
- #
74
- # _@param_ `model` — model to save
75
- #
76
- # _@return_ — `true` if successful
77
- sig { params(model: Handlers::Model).returns(T::Boolean) }
78
- def self.save(model); end
79
-
80
- # Similar to {ActiveRecord::Base#save!} but in case of constraint violations,
81
- # it raises {ConstraintViolation} and `errors` are populated.
82
- # Aside from `model`, it takes the same arguments as
83
- # {ActiveRecord::Base#save!}
84
- #
85
- # _@param_ `model` — model to save
86
- sig { params(model: Handlers::Model).returns(T::Boolean) }
87
- def self.save!(model); end
88
-
89
- # Similar to {ActiveRecord::Base#destroy} but in case of constraint
90
- # violations, `false` is returned and `errors` are populated.
91
- #
92
- # _@param_ `model` — model to destroy
93
- #
94
- # _@return_ — the destroyed model
95
- sig { params(model: Handlers::Model).returns(Handlers::Model) }
96
- def self.destroy(model); end
97
-
98
- # Included in all exceptions triggered by Iry, this allows to rescue any
99
- # gem-related exception by rescuing {Iry::Error}
100
- module Error
101
- end
102
-
103
- # Raised when constraints have been violated and have been converted to
104
- # model errors, on {ActiveRecord::Base#save!} calls, to simulate a behavior
105
- # similar to {ActiveRecord::RecordInvalid} when it's raised
106
- class ConstraintViolation < ActiveRecord::RecordInvalid
107
- include Iry::Error
108
- end
109
-
110
- # Raised when constraints errors happen and go through Iry, even if these
111
- # are not handled. This class inherits from {ActiveRecord::StatementInvalid}
112
- # to maximize compatibility with existing code
113
- class StatementInvalid < ActiveRecord::StatementInvalid
114
- include Iry::Error
115
-
116
- # sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
117
- # sord omit - no YARD type given for "**kwargs", using untyped
118
- # _@param_ `message`
119
- #
120
- # _@param_ `record`
121
- #
122
- # _@param_ `error`
123
- sig do
124
- params(
125
- message: T.nilable(String),
126
- record: Handlers::Model,
127
- error: ActiveModel::Error,
128
- kwargs: T.untyped
129
- ).void
130
- end
131
- def initialize(message = nil, record:, error:, **kwargs); end
132
-
133
- # _@return_ — model affected by the constraint violation
134
- sig { returns(Handlers::Model) }
135
- attr_reader :record
136
-
137
- # sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
138
- # _@return_ — error attached to the `record` for the
139
- # constraint violation
140
- sig { returns(ActiveModel::Error) }
141
- attr_reader :error
142
- end
143
-
144
- # Overrides private API method {ActiveRecord#create_or_update} to handle
145
- # constraints and attach errors to the including model
146
- module Patch
147
- # Takes attributes as named arguments
148
- #
149
- # _@return_ — true if successful
150
- sig { returns(T::Boolean) }
151
- def create_or_update; end
152
- end
153
-
154
- # Class-level methods available to classes executing `include Iry`
155
- module Macros
156
- # Constraints by name
157
- sig { returns(T::Hash[String, Constraint]) }
158
- def constraints; end
159
-
160
- # Tracks check constraint for the given key and convert constraint errors into validation errors
161
- #
162
- # _@param_ `key` — key to apply validation errors to
163
- #
164
- # _@param_ `message` — the validation error message
165
- #
166
- # _@param_ `name` — constraint name. If omitted, it will be inferred using table name + key
167
- sig { params(key: Symbol, name: T.nilable(String), message: T.any(Symbol, String)).void }
168
- def check_constraint(key, name: nil, message: :invalid); end
169
-
170
- # Tracks exclusion constraint for the given key and convert constraint errors into validation errors
171
- #
172
- # _@param_ `key` — key to apply validation errors to
173
- #
174
- # _@param_ `message` — the validation error message
175
- #
176
- # _@param_ `name` — constraint name. If omitted, it will be inferred using table name + key
177
- sig { params(key: Symbol, name: T.nilable(String), message: T.any(Symbol, String)).void }
178
- def exclusion_constraint(key, name: nil, message: :taken); end
179
-
180
- # Tracks foreign key constraint for the given key (or keys) and convert constraint errors into validation errors
181
- #
182
- # _@param_ `key_or_keys` — key or array of keys to track the foreign key constraint of
183
- #
184
- # _@param_ `message` — the validation error message
185
- #
186
- # _@param_ `name` — constraint name. If omitted, it will be inferred using table name + keys
187
- #
188
- # _@param_ `error_key` — key to which the validation error will be applied to. If omitted, it will be applied to the first key
189
- sig do
190
- params(
191
- key_or_keys: T.any(Symbol, T::Array[Symbol]),
192
- name: T.nilable(String),
193
- message: T.any(Symbol, String),
194
- error_key: T.nilable(Symbol)
195
- ).void
196
- end
197
- def foreign_key_constraint(key_or_keys, name: nil, message: :required, error_key: nil); end
198
-
199
- # Tracks uniqueness constraint for the given key (or keys) and convert constraint errors into validation errors
200
- #
201
- # _@param_ `key_or_keys` — key or array of keys to track the uniqueness constraint of
202
- #
203
- # _@param_ `message` — the validation error message
204
- #
205
- # _@param_ `name` — constraint name. If omitted, it will be inferred using table name + keys
206
- #
207
- # _@param_ `error_key` — key to which the validation error will be applied to. If omitted, it will be applied to the first key
208
- sig do
209
- params(
210
- key_or_keys: T.any(Symbol, T::Array[Symbol]),
211
- name: T.nilable(String),
212
- message: T.any(Symbol, String),
213
- error_key: T.nilable(Symbol)
214
- ).void
215
- end
216
- def unique_constraint(key_or_keys, name: nil, message: :taken, error_key: nil); end
217
- end
218
-
219
- module Handlers
220
- # Interface for handlers of different database types
221
- # @abstract
222
- module Handler
223
- # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
224
- # _@param_ `err` — possible constraint error to handle
225
- #
226
- # _@return_ — true if this database handler is the correct one for this exception
227
- sig { params(err: ActiveRecord::StatementInvalid).returns(T::Boolean) }
228
- def handle?(err); end
229
-
230
- # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
231
- # _@param_ `err` — possible constraint error to handle
232
- #
233
- # _@param_ `model`
234
- #
235
- # _@return_ — `nil` if couldn't handle the error,
236
- # otherwise the {ActiveModel::Error} added to the model
237
- sig { params(err: ActiveRecord::StatementInvalid, model: Model).void }
238
- def handle(err, model); end
239
- end
240
-
241
- # Interface of the model class. This class is usually inherits from {ActiveRecord::Base}
242
- # @abstract
243
- module ModelClass
244
- sig { returns(String) }
245
- def table_name; end
246
-
247
- sig { returns(T::Hash[String, Constraint]) }
248
- def constraints; end
249
- end
250
-
251
- # Interface of the model that should be used to handle constraints.
252
- # This object is an instance of {ActiveRecord::Base}
253
- # @abstract
254
- module Model
255
- # sord warn - ActiveModel::Errors wasn't able to be resolved to a constant in this project
256
- sig { returns(ActiveModel::Errors) }
257
- def errors; end
258
-
259
- sig { returns(ModelClass) }
260
- def class; end
261
- end
262
-
263
- # PostgreSQL handler through `pg` gem
264
- # @private
265
- module PG
266
- extend Iry::Handlers::PG
267
- REGEX = T.let(%r{
268
- (?:
269
- unique\sconstraint|
270
- check\sconstraint|
271
- exclusion\sconstraint|
272
- foreign\skey\sconstraint
273
- )
274
- \s"([^"]+)"
275
- }x, T.untyped)
276
-
277
- # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
278
- # When true, the handler is able to handle this exception, representing a constraint error in PostgreSQL.
279
- # This method must ensure not to raise exception in case the postgresql adapter is missing and as such, the
280
- # postgres constant is undefined
281
- #
282
- # _@param_ `err`
283
- sig { params(err: ActiveRecord::StatementInvalid).returns(T::Boolean) }
284
- def handle?(err); end
285
-
286
- # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
287
- # Appends constraint errors as model errors
288
- #
289
- # _@param_ `err`
290
- #
291
- # _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
292
- #
293
- # _@return_ — if handled constraint, returns the
294
- # error attached to the model. If constraint wasn't handled or handling
295
- # failed, `nil` is returned
296
- sig { params(err: ActiveRecord::StatementInvalid, model: Model).void }
297
- def handle(err, model); end
298
-
299
- # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
300
- # When true, the handler is able to handle this exception, representing a constraint error in PostgreSQL.
301
- # This method must ensure not to raise exception in case the postgresql adapter is missing and as such, the
302
- # postgres constant is undefined
303
- #
304
- # _@param_ `err`
305
- sig { params(err: ActiveRecord::StatementInvalid).returns(T::Boolean) }
306
- def self.handle?(err); end
307
-
308
- # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
309
- # Appends constraint errors as model errors
310
- #
311
- # _@param_ `err`
312
- #
313
- # _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
314
- #
315
- # _@return_ — if handled constraint, returns the
316
- # error attached to the model. If constraint wasn't handled or handling
317
- # failed, `nil` is returned
318
- sig { params(err: ActiveRecord::StatementInvalid, model: Model).void }
319
- def self.handle(err, model); end
320
- end
321
-
322
- # Catch-all handler for unrecognized database adapters
323
- # @private
324
- module Null
325
- extend Iry::Handlers::Null
326
-
327
- # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
328
- # Returns always true, catching any unhandled database exception
329
- #
330
- # _@param_ `err`
331
- sig { params(err: T.any(StandardError, ActiveRecord::StatementInvalid)).returns(T::Boolean) }
332
- def handle?(err); end
333
-
334
- # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
335
- # Return always false, failing to handle any constraint
336
- #
337
- # _@param_ `err`
338
- #
339
- # _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
340
- sig { params(err: ActiveRecord::StatementInvalid, model: Model).void }
341
- def handle(err, model); end
342
-
343
- # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
344
- # Returns always true, catching any unhandled database exception
345
- #
346
- # _@param_ `err`
347
- sig { params(err: T.any(StandardError, ActiveRecord::StatementInvalid)).returns(T::Boolean) }
348
- def self.handle?(err); end
349
-
350
- # sord warn - ActiveRecord::StatementInvalid wasn't able to be resolved to a constant in this project
351
- # Return always false, failing to handle any constraint
352
- #
353
- # _@param_ `err`
354
- #
355
- # _@param_ `model` — should inherit {ActiveRecord::Base} and`include Iry` to match the interface
356
- sig { params(err: ActiveRecord::StatementInvalid, model: Model).void }
357
- def self.handle(err, model); end
358
- end
359
- end
360
-
361
- # Main function to kick-off **Iry** constraint-checking mechanism
362
- # If interested in adding support for other databases beside Postgres, modify this file.
363
- # @private
364
- module Callbacks
365
- extend Iry::Callbacks
366
-
367
- # _@param_ `model`
368
- sig { params(model: Handlers::Model).void }
369
- def around_save(model); end
370
-
371
- # _@param_ `model`
372
- sig { params(model: Handlers::Model).void }
373
- def self.around_save(model); end
374
- end
375
-
376
- # Interface representing a constraint.
377
- # A constraint has a name and can apply errors to an object inheriting from {ActiveRecord::Base}
378
- # @abstract
379
- module Constraint
380
- # sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
381
- # Sets validation errors on the model
382
- #
383
- # _@param_ `model`
384
- sig { params(model: Handlers::Model).returns(ActiveModel::Error) }
385
- def apply(model); end
386
-
387
- # Name of the constraint to be caught from the database
388
- sig { returns(String) }
389
- def name; end
390
-
391
- # Message to be attached as validation error to the model
392
- # (see Handlers::Model)
393
- sig { returns(T.any(Symbol, String)) }
394
- def message; end
395
-
396
- class Check
397
- # Infers the check constraint name based on key and table name
398
- #
399
- # _@param_ `key`
400
- #
401
- # _@param_ `table_name`
402
- sig { params(key: Symbol, table_name: String).returns(String) }
403
- def self.infer_name(key, table_name); end
404
-
405
- # _@param_ `key` — key to apply error message for check constraint to
406
- #
407
- # _@param_ `message` — the validation error message
408
- #
409
- # _@param_ `name` — constraint name
410
- sig { params(key: Symbol, name: String, message: T.any(Symbol, String)).void }
411
- def initialize(key, name:, message: :invalid); end
412
-
413
- # sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
414
- # _@param_ `model`
415
- sig { params(model: Handlers::Model).returns(ActiveModel::Error) }
416
- def apply(model); end
417
-
418
- sig { returns(Symbol) }
419
- attr_accessor :key
420
-
421
- sig { returns(T.any(Symbol, String)) }
422
- attr_accessor :message
423
-
424
- sig { returns(String) }
425
- attr_accessor :name
426
- end
427
-
428
- class Unique
429
- MAX_INFER_NAME_BYTE_SIZE = T.let(62, T.untyped)
430
-
431
- # Infers the unique constraint name based on keys and table name
432
- #
433
- # _@param_ `keys`
434
- #
435
- # _@param_ `table_name`
436
- sig { params(keys: T::Array[Symbol], table_name: String).returns(String) }
437
- def self.infer_name(keys, table_name); end
438
-
439
- # _@param_ `keys` — array of keys to track the uniqueness constraint of
440
- #
441
- # _@param_ `message` — the validation error message
442
- #
443
- # _@param_ `name` — constraint name
444
- #
445
- # _@param_ `error_key` — key to which the validation error will be applied to
446
- sig do
447
- params(
448
- keys: T::Array[Symbol],
449
- name: String,
450
- error_key: Symbol,
451
- message: T.any(Symbol, String)
452
- ).void
453
- end
454
- def initialize(keys, name:, error_key:, message: :taken); end
455
-
456
- # sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
457
- # _@param_ `model`
458
- sig { params(model: Handlers::Model).returns(ActiveModel::Error) }
459
- def apply(model); end
460
-
461
- sig { returns(T::Array[Symbol]) }
462
- attr_accessor :keys
463
-
464
- sig { returns(T.any(Symbol, String)) }
465
- attr_accessor :message
466
-
467
- sig { returns(String) }
468
- attr_accessor :name
469
-
470
- sig { returns(Symbol) }
471
- attr_accessor :error_key
472
- end
473
-
474
- class Exclusion
475
- # Infers the exclusion constraint name based on key and table name
476
- #
477
- # _@param_ `key`
478
- #
479
- # _@param_ `table_name`
480
- sig { params(key: Symbol, table_name: String).returns(String) }
481
- def self.infer_name(key, table_name); end
482
-
483
- # _@param_ `key` — key to apply error message for exclusion constraint to
484
- #
485
- # _@param_ `message` — the validation error message
486
- #
487
- # _@param_ `name` — constraint name
488
- sig { params(key: Symbol, name: String, message: T.any(Symbol, String)).void }
489
- def initialize(key, name:, message: :taken); end
490
-
491
- # sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
492
- # _@param_ `model`
493
- sig { params(model: Handlers::Model).returns(ActiveModel::Error) }
494
- def apply(model); end
495
-
496
- sig { returns(Symbol) }
497
- attr_accessor :key
498
-
499
- sig { returns(T.any(Symbol, String)) }
500
- attr_accessor :message
501
-
502
- sig { returns(String) }
503
- attr_accessor :name
504
- end
505
-
506
- class ForeignKey
507
- # Infers the unique constraint name based on keys and table name
508
- #
509
- # _@param_ `keys`
510
- #
511
- # _@param_ `table_name`
512
- sig { params(keys: T::Array[Symbol], table_name: String).returns(String) }
513
- def self.infer_name(keys, table_name); end
514
-
515
- # _@param_ `keys` — array of keys to track the uniqueness constraint of
516
- #
517
- # _@param_ `message` — the validation error message
518
- #
519
- # _@param_ `name` — constraint name
520
- #
521
- # _@param_ `error_key` — key to which the validation error will be applied to
522
- sig do
523
- params(
524
- keys: T::Array[Symbol],
525
- name: String,
526
- error_key: Symbol,
527
- message: T.any(Symbol, String)
528
- ).void
529
- end
530
- def initialize(keys, name:, error_key:, message: :required); end
531
-
532
- # sord warn - ActiveModel::Error wasn't able to be resolved to a constant in this project
533
- # _@param_ `model`
534
- sig { params(model: Handlers::Model).returns(ActiveModel::Error) }
535
- def apply(model); end
536
-
537
- sig { returns(T::Array[Symbol]) }
538
- attr_accessor :keys
539
-
540
- sig { returns(T.any(Symbol, String)) }
541
- attr_accessor :message
542
-
543
- sig { returns(String) }
544
- attr_accessor :name
545
-
546
- sig { returns(Symbol) }
547
- attr_accessor :error_key
548
- end
549
- end
550
-
551
- # Implementation of {Iry} methods, helps ensuring the main module focus on
552
- # documentation
553
- module TransformConstraints
554
- extend Iry::TransformConstraints
555
-
556
- # _@param_ `model`
557
- sig { params(model: Handlers::Model, block: T.untyped).void }
558
- def handle_constraints(model, &block); end
559
-
560
- # _@param_ `model`
561
- sig { params(model: Handlers::Model, block: T.untyped).returns(Handlers::Model) }
562
- def handle_constraints!(model, &block); end
563
-
564
- # Tracks constraints of models saved as a consequence of saving another
565
- # model. This usually represents a situation of model using
566
- # `accepts_nested_attributes_for`
567
- #
568
- # _@param_ `model`
569
- sig { params(model: Handlers::Model, block: T.untyped).returns(Handlers::Model) }
570
- def nested_constraints!(model, &block); end
571
-
572
- # _@param_ `model`
573
- sig { params(model: Handlers::Model).returns(T::Boolean) }
574
- def save(model); end
575
-
576
- # _@param_ `model`
577
- sig { params(model: Handlers::Model).returns(T::Boolean) }
578
- def save!(model); end
579
-
580
- # _@param_ `model`
581
- sig { params(model: Handlers::Model).returns(Handlers::Model) }
582
- def destroy(model); end
583
-
584
- # _@param_ `model`
585
- sig { params(model: Handlers::Model, block: T.untyped).void }
586
- def self.handle_constraints(model, &block); end
587
-
588
- # _@param_ `model`
589
- sig { params(model: Handlers::Model, block: T.untyped).returns(Handlers::Model) }
590
- def self.handle_constraints!(model, &block); end
591
-
592
- # Tracks constraints of models saved as a consequence of saving another
593
- # model. This usually represents a situation of model using
594
- # `accepts_nested_attributes_for`
595
- #
596
- # _@param_ `model`
597
- sig { params(model: Handlers::Model, block: T.untyped).returns(Handlers::Model) }
598
- def self.nested_constraints!(model, &block); end
599
-
600
- # _@param_ `model`
601
- sig { params(model: Handlers::Model).returns(T::Boolean) }
602
- def self.save(model); end
603
-
604
- # _@param_ `model`
605
- sig { params(model: Handlers::Model).returns(T::Boolean) }
606
- def self.save!(model); end
607
-
608
- # _@param_ `model`
609
- sig { params(model: Handlers::Model).returns(Handlers::Model) }
610
- def self.destroy(model); end
611
- end
612
- end