jet_set 0.3.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
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