jet_set 0.3.2 → 0.5.3

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
- SHA1:
3
- metadata.gz: 9d9c31fea3ab85535b7334a1bcfea9f5a15577f6
4
- data.tar.gz: 9dff8880d96dc20c7674a64e66553ac104da18be
2
+ SHA256:
3
+ metadata.gz: bb3d54a41c9a91c8761053dd1ba08314f3f5416f9b9762cace0758bdb32e2c5f
4
+ data.tar.gz: 94c834a0a75d2cf2bae2a25d8e57b24ac68b7870e6e61ed6fc1fafb62c9e5a8c
5
5
  SHA512:
6
- metadata.gz: 23b7ed643ec6ad827879e7d6f2e1e9d0f038a78cd7051483de3c85f6ea1f32d02361d098ecbeab6648375b5d206367028bdd16310ca8a11bd76962ece12b0258
7
- data.tar.gz: c59832f80bbf2996665384963be940e81ae9bc26a68a28f6d5bb212e28c1899710c544cfb5eeff48564e5a9a7458453eddaa475708d5ad11809a765111bb8964
6
+ metadata.gz: 4e08aeb9e15d4918b310dcf33b03e9df48fa555ade341901518b21fa51b67eb4c22b98d184922ef7291baeb3edf08171e2737e90580b61e563e61f9452159645
7
+ data.tar.gz: 024b1e91903efb225aac4142932ce67abed52eb16681214ccf2a6803d72c929c77e183fb1352e58124bec1a70b2786320eabf426bd212a99ae0fcdf6a1d6cc3d
data/Gemfile CHANGED
@@ -2,4 +2,3 @@ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
-
data/README.md CHANGED
@@ -1,9 +1,8 @@
1
1
  # JetSet ![Build Status](https://travis-ci.org/cylon-v/jet_set.svg?branch=master)
2
2
 
3
-
4
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/jet_set`. To experiment with that code, run `bin/console` for an interactive prompt.
5
-
6
- TODO: Delete this and the text above, and describe your gem
3
+ JetSet is a data mapping framework for domain-driven developers who think that SQL is the best tool for data querying.
4
+ JetSet is built on top of [Sequel](https://github.com/jeremyevans/sequel) ORM and it's just an abstraction for making
5
+ the persistence of mapped objects invisible.
7
6
 
8
7
  ## Installation
9
8
 
@@ -23,7 +22,156 @@ Or install it yourself as:
23
22
 
24
23
  ## Usage
25
24
 
26
- TODO: Write usage instructions here
25
+ ### Initialization
26
+ Open DB connection, see [Sequel docs](https://sequel.jeremyevans.net/rdoc/files/doc/opening_databases_rdoc.html):
27
+ ```ruby
28
+ @connection = Sequel.connect('sqlite:/') # you can connect to any DB supported by Sequel
29
+ ```
30
+
31
+ Create a mapping of your model, details described [here]:
32
+ ```ruby
33
+ class Mapping
34
+ def self.load_mapping
35
+ JetSet::map do
36
+ entity User do
37
+ field :first_name # reqular field
38
+ collection :invoices, type: Invoice # "has many" association
39
+ reference :plan, type: Plan, weak: true # "belongs to" association
40
+ end
41
+ end
42
+ end
43
+ end
44
+ ```
45
+
46
+ Init JetSet environment on start of your application:
47
+ ```ruby
48
+ JetSet::init(Mapping.load_mapping, @container)
49
+ ```
50
+
51
+ Open JetSet session:
52
+ ```ruby
53
+ @jet_set = JetSet::open_session(@connection)
54
+ ```
55
+ For web-applications it's reasonable to bind JetSet session to request lifetime -
56
+ all modification operations in an MVC action can represent a ["Unit of Work"](https://martinfowler.com/eaaCatalog/unitOfWork.html).
57
+
58
+ ### Object model
59
+ Using JetSet you can wrap an application domain model and purely implement "Persistence Ignorance" approach.
60
+ The model objects are pure Ruby objects without any noisy stuff like annotations, inline mapping, etc:
61
+ ```ruby
62
+ class User
63
+ attr_reader :invoices
64
+
65
+ def initialize(attrs = {})
66
+ @first_name = attrs[:first_name]
67
+ @last_name = attrs[:last_name]
68
+ @invoices = []
69
+ end
70
+
71
+ def add_invoice(invoice)
72
+ @invoices << invoice
73
+ end
74
+ end
75
+
76
+ class Invoice
77
+ attr_reader :created_at, :amount
78
+
79
+ def initialize(attrs = {})
80
+ @created_at = DateTime.now
81
+ @amount = attrs[:amount] || 0
82
+ end
83
+ end
84
+ ```
85
+
86
+ ### Object model tracking and saving
87
+ Create an objects which is described in the mapping:
88
+ ```ruby
89
+ user = User.new(first_name: 'Ivan', last_name: 'Ivanov')
90
+ invoice = Invoice.new(created_at: DateTime.now, user: user, amount: 100.0)
91
+ ```
92
+
93
+ Attach them to the session:
94
+ ```ruby
95
+ @session.attach(invoice, user)
96
+ ```
97
+ It makes the objects tracked by JetSet.
98
+
99
+ Finalize the session:
100
+ ```ruby
101
+ @session.finalize
102
+ ```
103
+ It saves all added/changed objects to the database.
104
+
105
+ ### Object model loading
106
+
107
+ ```ruby
108
+ user_query = <<~SQL
109
+ SELECT
110
+ u.* AS ENTITY user
111
+ FROM users u
112
+ LIMIT 1
113
+ SQL
114
+
115
+ invoices_sql = <<~SQL
116
+ SELECT
117
+ i.* AS ENTITY invoice
118
+ WHERE i.user_id = :user_id
119
+ SQL
120
+
121
+ customer = @session.fetch(User, user_query) do |user|
122
+ preload(user, :invoices, invoices_sql, user_id: user.id)
123
+ end
124
+ ```
125
+ All loaded objects are already attached to the session and you can perform a changes which will be saved after the session finalization:
126
+
127
+ ```ruby
128
+ customer.invoices[0].apply # changes invoice state
129
+ @session.finalize
130
+ ```
131
+
132
+ Do not load your object model just for drawing a views. For showing a results just use Sequel without any object mappings:
133
+ ```ruby
134
+ result = @connection[:user].where(role: 'admin').to_a
135
+ json = JSON.generate(data: result)
136
+ ```
137
+ In other words, following [CQS](https://en.wikipedia.org/wiki/Command%E2%80%93query_separation) approach you can
138
+ load your model for a command but not for a query.
139
+
140
+ ### Validation
141
+ Simple validation is optional feature provided by JetSet out of the box. To add this to your domain object you just need
142
+ to include module `JetSet::Validations` and use `validate` statements:
143
+
144
+ ```ruby
145
+ require 'jet_set/validations'
146
+
147
+ class User
148
+ include JetSet::Validations
149
+ validate :name, 'cannot be empty', -> (value) {!value.nil? && !value.empty?}
150
+ validate :email, type: :string, presence: true
151
+ validate :email, 'should be valid email address', -> (value) {value.match(...)}
152
+
153
+ def initialize(attrs = {})
154
+ @name = attrs[:name]
155
+ end
156
+ end
157
+ ```
158
+ JetSet uses such validations automatically on saving objects in the database. Also you can invoke validation manually,
159
+ i.e. in unit tests, using `validate!` method:
160
+
161
+ ```ruby
162
+ user = User.new(name: nil)
163
+ user.validate! # raises JetSet::ValidationError
164
+ ```
165
+
166
+ `JetSet::ValidationError` contains details regarding invalid items like:
167
+
168
+ ```ruby
169
+ error.invalid_items # => {name: 'cannot be empty'}
170
+ ```
171
+
172
+
173
+
174
+ You can find more interesting examples in [JetSet integration tests](https://github.com/cylon-v/jet_set/tree/master/spec/integration).
27
175
 
28
176
  ## Development
29
177
 
data/jet_set.gemspec CHANGED
@@ -30,12 +30,11 @@ Gem::Specification.new do |spec|
30
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
31
  spec.require_paths = ['lib']
32
32
 
33
- spec.add_dependency 'sequel', '~> 5.4.0'
34
- spec.add_dependency 'hypo', '~> 0.9.0'
35
-
36
- spec.add_development_dependency 'bundler', '~> 1.15'
37
- spec.add_development_dependency 'rake', '~> 10.0'
38
- spec.add_development_dependency 'rspec', '~> 3.0'
39
- spec.add_development_dependency 'sqlite3', '~> 1.3'
40
- spec.add_development_dependency 'simplecov', '~> 0.16'
33
+ spec.add_dependency 'sequel', '>= 5.4.0'
34
+ spec.add_dependency 'hypo', '>= 1.0.0'
35
+ spec.add_development_dependency 'bundler', '>= 2.1'
36
+ spec.add_development_dependency 'rake', '>= 10.0'
37
+ spec.add_development_dependency 'rspec', '>= 3.0'
38
+ spec.add_development_dependency 'sqlite3', '>= 1.3'
39
+ spec.add_development_dependency 'simplecov', '>= 0.16'
41
40
  end
data/lib/jet_set.rb CHANGED
@@ -3,6 +3,9 @@ require 'sequel'
3
3
  require 'sequel/extensions/inflector'
4
4
  require 'jet_set/environment'
5
5
  require 'jet_set/mapping'
6
+ require 'jet_set/validations'
7
+ require 'jet_set/validation_error'
8
+ require 'jet_set/validation_definition_error'
6
9
  require 'jet_set/version'
7
10
 
8
11
  module JetSet
@@ -1,5 +1,6 @@
1
1
  require 'jet_set/mixin/identity'
2
2
  require 'jet_set/mixin/entity'
3
+ require 'jet_set/validations'
3
4
 
4
5
  module JetSet
5
6
  # A converter of a pure Ruby object to JetSet trackable object.
@@ -22,6 +23,7 @@ module JetSet
22
23
 
23
24
  object.extend(Identity)
24
25
  object.extend(Entity)
26
+ object.extend(Validations)
25
27
  end
26
28
  end
27
29
  end
@@ -15,7 +15,8 @@ module JetSet
15
15
  @container = container
16
16
 
17
17
  @mapping.entity_mappings.values.each do |entity_mapping|
18
- container.register(entity_mapping.type)
18
+ entity_name = "jet_set__#{entity_mapping.type.name.underscore}".to_sym
19
+ container.register(entity_mapping.type, entity_name)
19
20
  end
20
21
  end
21
22
 
@@ -29,22 +30,29 @@ module JetSet
29
30
  # "SELECT u.name AS customer__name from users u"
30
31
  def map(type, row_hash, session, prefix = type.name.underscore)
31
32
  entity_name = type.name.underscore.to_sym
33
+ resolve_name = "jet_set__#{type.name.underscore}".to_sym
32
34
  entity_mapping = @mapping.get(entity_name)
33
35
  row = Row.new(row_hash, entity_mapping.fields, prefix)
34
- object = @container.resolve(entity_name)
35
- entity = @entity_builder.create(object)
36
- entity.load_attributes!(row.attributes)
37
36
 
37
+ reference_hash = {}
38
38
  row.reference_names.each do |reference_name|
39
39
  if entity_mapping.references.key? reference_name.to_sym
40
40
  reference_id_name = reference_name + '__id'
41
41
  unless row_hash[reference_id_name.to_sym].nil?
42
42
  type = entity_mapping.references[reference_name.to_sym].type
43
- entity.set_reference! reference_name, map(type, row_hash, session, reference_name)
43
+ reference_hash[reference_name.to_sym] = map(type, row_hash, session, reference_name)
44
44
  end
45
45
  end
46
46
  end
47
47
 
48
+ object = @container.resolve(resolve_name, row.attributes_hash.merge(reference_hash))
49
+ entity = @entity_builder.create(object)
50
+ entity.load_attributes!(row.attributes)
51
+
52
+ reference_hash.each do |key, value|
53
+ entity.set_reference! key.to_s, value
54
+ end
55
+
48
56
  session.attach(entity)
49
57
  entity
50
58
  end
@@ -6,7 +6,7 @@ module JetSet
6
6
  module Entity
7
7
  # Loads the entity attributes.
8
8
  # Parameters:
9
- # +attributes+:: a hash of attributes in format :field => :value
9
+ # +attributes+:: an array of key-pairs in format :field => :value
10
10
  def load_attributes!(attributes)
11
11
  attributes.each do |attribute|
12
12
  name = "@#{attribute[:field]}"
@@ -77,6 +77,8 @@ module JetSet
77
77
  # Parameters:
78
78
  # +sequel+:: Sequel sequel
79
79
  def flush(sequel)
80
+ validate! if respond_to? :validate!
81
+
80
82
  table_name = self.class.name.underscore.pluralize.to_sym
81
83
  table = sequel[table_name]
82
84
  entity_name = self.class.name.underscore.to_sym
@@ -113,12 +115,14 @@ module JetSet
113
115
  values << value.instance_variable_get('@id')
114
116
  end
115
117
  end
118
+
116
119
  new_id = table.insert(fields, values)
117
120
  @__attributes['@id'] = Attribute.new('@id', new_id)
118
121
  @id = new_id
119
122
  elsif dirty?
120
123
  attributes = {}
121
124
  dirty_attributes.each {|attribute| attributes[attribute.name.sub('@', '')] = instance_variable_get(attribute.name)}
125
+
122
126
  if attributes.keys.length > 0
123
127
  table.where(id: @id).update(attributes)
124
128
  end
data/lib/jet_set/row.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  module JetSet
2
2
  # A container for fields/references extraction logic
3
3
  class Row
4
- attr_reader :attributes, :reference_names
4
+ attr_reader :attributes, :attributes_hash, :reference_names
5
5
 
6
6
  def initialize(row_hash, entity_fields, prefix)
7
7
  keys = row_hash.keys.map {|key| key.to_s}
@@ -10,6 +10,11 @@ module JetSet
10
10
  .select {|key| entity_fields.include? key.sub(prefix + '__', '')}
11
11
  .map {|key| {field: key.sub(prefix + '__', ''), value: row_hash[key.to_sym]}}
12
12
 
13
+ @attributes_hash = {}
14
+ @attributes.each do |attr|
15
+ @attributes_hash[attr[:field].to_sym] = attr[:value]
16
+ end
17
+
13
18
  @reference_names = keys.select {|key| !key.start_with?(prefix) && key.include?('__')}
14
19
  .map {|key| key.split('__')[0]}
15
20
  .uniq
@@ -14,6 +14,7 @@ module JetSet
14
14
  @query_parser = query_parser
15
15
  @entity_builder = entity_builder
16
16
  @dependency_graph = dependency_graph
17
+ @mutex = Mutex.new
17
18
  end
18
19
 
19
20
  # Fetches root entity using a result of +execute+ method.
@@ -87,9 +88,17 @@ module JetSet
87
88
  end
88
89
  end
89
90
 
90
- to_attach.each do |object|
91
- obj = object.kind_of?(Entity) ? object : @entity_builder.create(object)
92
- @objects << obj
91
+ @mutex.synchronize do
92
+ to_attach.each do |object|
93
+ if object.kind_of?(Entity)
94
+ obj = object
95
+ else
96
+ obj = @entity_builder.create(object)
97
+ obj.validate! if obj.respond_to? :validate!
98
+ end
99
+
100
+ @objects << obj
101
+ end
93
102
  end
94
103
  end
95
104
 
@@ -100,9 +109,15 @@ module JetSet
100
109
  dirty_objects = @objects.select {|object| object.dirty?}
101
110
  ordered_objects = @dependency_graph.order(dirty_objects)
102
111
 
103
- if ordered_objects.length > 0
104
- @sequel.transaction do
105
- ordered_objects.each{|obj| obj.flush(@sequel)}
112
+ begin
113
+ if ordered_objects.length > 0
114
+ @sequel.transaction do
115
+ ordered_objects.each{|obj| obj.flush(@sequel)}
116
+ end
117
+ end
118
+ ensure
119
+ @mutex.synchronize do
120
+ @objects = []
106
121
  end
107
122
  end
108
123
  end
@@ -0,0 +1,4 @@
1
+ module JetSet
2
+ class ValidationDefinitionError < StandardError
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ module JetSet
2
+ class ValidationError < StandardError
3
+ attr_reader :invalid_items
4
+
5
+ def initialize(message, invalid_items = {})
6
+ super(message)
7
+ @invalid_items = invalid_items
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,97 @@
1
+ require 'jet_set/validation_error'
2
+
3
+ module JetSet
4
+ # Optional validation decorator. Adds validation logic to pure Ruby objects.
5
+ module Validations
6
+ # The method runs all validations declared in the model
7
+ def validate!
8
+ @to_skip ||= []
9
+
10
+ validations = self.class.class_variable_defined?(:@@validations) ? self.class.class_variable_get(:@@validations) : {}
11
+ attributes = validations.keys - @to_skip
12
+ invalid_items = []
13
+
14
+ attributes.each do |attribute|
15
+ attribute_validations = validations[attribute] || []
16
+
17
+ error = nil
18
+ attribute_validations.each do |validation|
19
+ value = instance_variable_get("@#{attribute}")
20
+ if validation[:func].call(value) == false
21
+ error = validation[:message]
22
+ break
23
+ end
24
+ end
25
+ invalid_items << {"#{attribute}": error} if error
26
+ end
27
+
28
+ raise ValidationError.new("#{self.class.name} is invalid", invalid_items) if invalid_items.length > 0
29
+ end
30
+
31
+ # Disables attribute validation for edge cases
32
+ def do_not_validate(*attributes)
33
+ @to_skip ||= []
34
+ attributes.each { |a| @to_skip << a}
35
+ end
36
+
37
+ def self.included(base)
38
+ base.extend(ClassMethods)
39
+ end
40
+
41
+ module ClassMethods
42
+ # Adds a validation to an attribute of the entity
43
+ # Parameters:
44
+ # +attribute_name+:: +Symbol+ attribute name
45
+ # +options+ || +message+:: validation options {type, presence, message, custom} or just a message
46
+ # +func+:: boolean proc with a check for validity
47
+ def validate(attribute_name, options, func = nil)
48
+ validations = self.class_variable_defined?(:@@validations) ? self.class_variable_get(:@@validations) : {}
49
+ validations[attribute_name] ||= []
50
+
51
+ if options.is_a?(Hash)
52
+ if options.has_key?(:type)
53
+ validations[attribute_name] << validate_type(options[:type])
54
+ end
55
+
56
+ if options[:presence] == true
57
+ validations[attribute_name] << validate_presence
58
+ end
59
+
60
+ message = options[:message]
61
+ elsif options.is_a?(String)
62
+ message = options
63
+ else
64
+ raise ValidationDefinitionError, "Validation definition of attribute #{attribute_name} is incorrect."
65
+ end
66
+
67
+ func ||= options[:custom]
68
+
69
+ unless func.nil?
70
+ validations[attribute_name] << {func: func, message: message}
71
+ end
72
+
73
+ self.class_variable_set(:@@validations, validations)
74
+ end
75
+
76
+ private
77
+
78
+ def validate_presence
79
+ {message: 'cannot be blank', func: -> (value) {!value.nil? && value != ''}}
80
+ end
81
+
82
+ def validate_type(type)
83
+ unless [:numeric, :string, :boolean].include?(type)
84
+ raise ValidationDefinitionError, "the type should be :numeric, :string or :boolean"
85
+ end
86
+
87
+ checks = {
88
+ numeric: -> (value) {value.is_a?(Numeric)},
89
+ string: -> (value) {value.is_a?(String)},
90
+ boolean: -> (value) {!!value == value}
91
+ }
92
+
93
+ {message: "should be #{type}", func: -> (value) {value.nil? || checks[type].call(value)}}
94
+ end
95
+ end
96
+ end
97
+ end
@@ -1,3 +1,3 @@
1
1
  module JetSet
2
- VERSION = "0.3.2"
2
+ VERSION = "0.5.3"
3
3
  end
metadata CHANGED
@@ -1,111 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jet_set
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Kalinkin
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-06 00:00:00.000000000 Z
11
+ date: 2021-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 5.4.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 5.4.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: hypo
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.9.0
33
+ version: 1.0.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.9.0
40
+ version: 1.0.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '1.15'
47
+ version: '2.1'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '1.15'
54
+ version: '2.1'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '10.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '10.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '3.0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: sqlite3
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '1.3'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '1.3'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: simplecov
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - "~>"
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0.16'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - "~>"
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.16'
111
111
  description: ''
@@ -143,14 +143,16 @@ files:
143
143
  - lib/jet_set/reference.rb
144
144
  - lib/jet_set/row.rb
145
145
  - lib/jet_set/session.rb
146
+ - lib/jet_set/validation_definition_error.rb
147
+ - lib/jet_set/validation_error.rb
148
+ - lib/jet_set/validations.rb
146
149
  - lib/jet_set/version.rb
147
- - test.rb
148
150
  homepage: https://github.com/cylon-v/jet_set
149
151
  licenses:
150
152
  - MIT
151
153
  metadata:
152
154
  allowed_push_host: https://rubygems.org
153
- post_install_message:
155
+ post_install_message:
154
156
  rdoc_options: []
155
157
  require_paths:
156
158
  - lib
@@ -165,9 +167,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
167
  - !ruby/object:Gem::Version
166
168
  version: '0'
167
169
  requirements: []
168
- rubyforge_project:
169
- rubygems_version: 2.6.12
170
- signing_key:
170
+ rubygems_version: 3.2.15
171
+ signing_key:
171
172
  specification_version: 4
172
173
  summary: JetSet is a microscopic ORM for DDD projects.
173
174
  test_files: []
data/test.rb DELETED
@@ -1,16 +0,0 @@
1
- class Test
2
- def initialize
3
- @method = 0
4
- end
5
-
6
- def calc
7
- @method = 1
8
- puts @method
9
- end
10
- end
11
-
12
- Test.define_method '@method=' do |value|
13
- @method = value + 5
14
- end
15
- test = Test.new
16
- test.calc