tiny_dyno 0.1.7 → 0.1.9

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
2
  SHA1:
3
- metadata.gz: 5260b6e451ace6f876c6778496c4e3fe1b5d7337
4
- data.tar.gz: a7ff251eba21480888716e3833f632f37916da1f
3
+ metadata.gz: 2a57635fe6ebcd452a54d007997380f6616bb0f3
4
+ data.tar.gz: 3e7518b99d5034175ea1781ac4f39812a722c7fa
5
5
  SHA512:
6
- metadata.gz: 3d12c868b43577811890db7671e8c8498d7d53fe146bedfc7ef66474f19d79ba177c8265de3667f6fd4680ecb46876f65af1171c2d80fec869412d3b86698e37
7
- data.tar.gz: 03b3fb815185cf31fddd8eadb81c1fcf4bcbc4694238c9d2242ea901bc0fffbb649d3d10ffdaa5981bd4b0cfaefad41c39a39bbd687142b4215203d7e4641628
6
+ metadata.gz: cd0dc92db501ed54364de063d527acb8ccb3a115ed27585a1c6c4c5f3e0f73ed65a9441d569150fb6c095f52b58eb0c59bcf313e21949a100cd92a6e3dada745
7
+ data.tar.gz: e6d2aee6af7d226e667e0e7f522d227daf5662b1f725c961b95ce097e4b5f4a8a88696d95cef8c4da2adc6afb4aa352affef3732e463a47973d2693e9efd345d
data/CHANGES.md ADDED
@@ -0,0 +1,12 @@
1
+ 0.1.9 (2015-07-01)
2
+ -----------------
3
+
4
+ * Fixes - clean up of a few stale require 'pry'
5
+
6
+ 0.1.8 (2015-07-01)
7
+ ------------------
8
+
9
+ * Fixes - Raise Error, if multiple hash keys are being defined
10
+ * Fixes - On Create use 'expected' clause to achieve intended behavior on create,
11
+ to not overwrite an existing record, but only create a new record
12
+
@@ -63,7 +63,7 @@ module TinyDyno
63
63
  # @since 2.1.0
64
64
  def attribute_change(attr)
65
65
  attr = database_field_name(attr)
66
- [changed_attributes[attr], attributes[attr]] if attribute_changed?(attr)
66
+ [changed_attributes[attr], attributes[attr]] if (attribute_changed?(attr) && !attr.nil?)
67
67
  end
68
68
 
69
69
  end
@@ -70,10 +70,10 @@ module TinyDyno
70
70
  # check that each option key relates to a hash_key present on the model
71
71
  # do not permit scan queries
72
72
  def valid_option_keys(options)
73
- options.keys.each do |name|
74
- named = name.to_s
75
- raise TinyDyno::Errors::HashKeysOnly.new(klass: self.class, name: named) unless hash_key_is_defined?(named)
76
- end
73
+ raise TinyDyno::Errors::HashKeyOnly.new(klass: self.class, name: 'primary_key') if primary_key.nil?
74
+ # options.keys.each do |name|
75
+ # named = name.to_s
76
+ # end
77
77
  end
78
78
 
79
79
  # minimimum implementation for now
@@ -3,27 +3,29 @@ require 'tiny_dyno/changeable'
3
3
  require 'tiny_dyno/fields'
4
4
  require 'tiny_dyno/stateful'
5
5
  require 'tiny_dyno/tables'
6
- require 'tiny_dyno/hash_keys'
6
+ require 'tiny_dyno/hash_key'
7
7
  require 'tiny_dyno/persistable'
8
+ require 'tiny_dyno/expected'
8
9
 
9
10
  module TinyDyno
10
11
  module DocumentComposition
11
12
  extend ActiveSupport::Concern
12
13
 
13
14
  include Attributes
15
+ include Expected
14
16
  include Changeable
15
17
  include Fields
16
- include HashKeys
18
+ include HashKey
17
19
  include Persistable
18
20
  include Stateful
19
21
  include Tables
20
22
 
21
-
22
23
  MODULES = [
23
24
  Attributes,
25
+ Expected,
24
26
  Changeable,
25
27
  Fields,
26
- HashKeys,
28
+ HashKey,
27
29
  Persistable,
28
30
  Stateful,
29
31
  Tables,
@@ -50,14 +50,13 @@ module TinyDyno
50
50
  end
51
51
  end
52
52
 
53
-
54
53
  # encoding: utf-8
55
54
  module TinyDyno
56
55
  module Errors
57
56
 
58
57
  # This error is raised, when a query is performed with fields specified
59
58
  # that are not HashKeys, which would result in a table scan
60
- class HashKeysOnly < TinyDynoError
59
+ class HashKeyOnly < TinyDynoError
61
60
 
62
61
  # Create the new error.
63
62
  #
@@ -76,3 +75,30 @@ module TinyDyno
76
75
  end
77
76
  end
78
77
  end
78
+
79
+ # encoding: utf-8
80
+ module TinyDyno
81
+ module Errors
82
+
83
+ # This error is raised, when a query is performed with fields specified
84
+ # that are not HashKeys, which would result in a table scan
85
+ class OnlyOneHashKeyPermitted < TinyDynoError
86
+
87
+ # Create the new error.
88
+ #
89
+ # @example Instantiate the error.
90
+ # OnlyOneHashKeyPermitted.new(Person, "gender")
91
+ #
92
+ # @param [ Class ] klass The model class.
93
+ # @param [ String, Symbol ] name The name of the attribute.
94
+ #
95
+ # @since 3.0.0
96
+ def initialize(klass:, name:)
97
+ super(
98
+ compose_message("you can only define one hash_key", { klass: klass.name, name: name })
99
+ )
100
+ end
101
+ end
102
+ end
103
+ end
104
+
@@ -0,0 +1,18 @@
1
+ module TinyDyno
2
+ module Expected
3
+ extend ActiveSupport::Concern
4
+
5
+ # insert Expected clause, which will ensure
6
+ # that INSERTs will only take place
7
+ # if there is no record with that hash key yet
8
+ def request_as_new_record(request)
9
+ request.merge({
10
+ expected: {
11
+ "#{ primary_key[:attr] }": {
12
+ comparison_operator: 'NULL'
13
+ }
14
+ }})
15
+ end
16
+
17
+ end
18
+ end
@@ -41,24 +41,24 @@ module TinyDyno
41
41
 
42
42
  private
43
43
 
44
- # Is the field included in the fields that were returned from the
45
- # database? We can apply the default if:
46
- # 1. The field is included in an only limitation (field: 1)
47
- # 2. The field is not excluded in a without limitation (field: 0)
48
- #
49
- # @example Is the field included?
50
- # field.included?(fields)
51
- #
52
- # @param [ Hash ] fields The field limitations.
53
- #
54
- # @return [ true, false ] If the field was included.
44
+ # # Is the field included in the fields that were returned from the
45
+ # # database? We can apply the default if:
46
+ # # 1. The field is included in an only limitation (field: 1)
47
+ # # 2. The field is not excluded in a without limitation (field: 0)
48
+ # #
49
+ # # @example Is the field included?
50
+ # # field.included?(fields)
51
+ # #
52
+ # # @param [ Hash ] fields The field limitations.
53
+ # #
54
+ # # @return [ true, false ] If the field was included.
55
+ # #
56
+ # # @since 2.4.4
57
+ # def included?(fields)
58
+ # (fields.values.first == 1 && fields[name.to_s] == 1) ||
59
+ # (fields.values.first == 0 && !fields.has_key?(name.to_s))
60
+ # end
55
61
  #
56
- # @since 2.4.4
57
- def included?(fields)
58
- (fields.values.first == 1 && fields[name.to_s] == 1) ||
59
- (fields.values.first == 0 && !fields.has_key?(name.to_s))
60
- end
61
-
62
62
  end
63
63
  end
64
64
  end
@@ -0,0 +1,109 @@
1
+ module TinyDyno
2
+ module HashKey
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ class_attribute :attribute_definitions, :key_schema, :primary_key
7
+
8
+ # TODO :local_secondary_indexes, :global_secondary_indexes
9
+ self.attribute_definitions ||= []
10
+ self.key_schema ||= []
11
+ self.primary_key ||= {}
12
+ end
13
+
14
+ # return all defined hash keys on an instantiated object
15
+ # for further use in DynamoDB queries, i.e. to look up an object
16
+ #
17
+ def hash_key_as_selector
18
+ { "#{ self.class.primary_key[:attr] }": attributes[self.class.primary_key[:attr]] }
19
+ end
20
+
21
+ module ClassMethods
22
+
23
+ # Defines the primary key for the Document
24
+ # Only one primary key = hash_key is allowed in DynamoDB
25
+ #
26
+ # @example Define a field.
27
+ # hash_key :score, :type => Integer
28
+ #
29
+ # @param [ Symbol ] name The name of the hash_key.
30
+ # @param [ Hash ] options The options to pass to the hash_key.
31
+ #
32
+ # @option options [ Class ] :type The type of the field.
33
+ # @option options [ String ] :label The label for the field.
34
+ #
35
+ # @return [ Field ] The generated field
36
+ def hash_key(name, options = {})
37
+ raise TinyDyno::Errors::OnlyOneHashKeyPermitted.new(klass: self.class, name: name) unless primary_key.empty?
38
+ named = name.to_s
39
+ attribute_definition = build_attribute_definition(named,options[:type])
40
+ key_schema = build_key_schema(named)
41
+ unless attribute_definition_meets_spec?(attribute_definition)
42
+ raise TinyDyno::Errors::InvalidHashKey.new(klass: self.class, name: name)
43
+ end
44
+ # we need the accessors as well
45
+ add_field(named, options)
46
+ self.attribute_definitions << attribute_definition
47
+ self.key_schema << key_schema
48
+ self.primary_key = {
49
+ attr: attribute_definition[:attribute_name],
50
+ attr_type: attribute_definition[:attribute_type],
51
+ key_type: key_schema[:key_type],
52
+ }
53
+ end
54
+
55
+ # convert a hash key into a format as expected by
56
+ # put_item and update_item request
57
+ def as_item_entry(hash_key)
58
+
59
+ end
60
+
61
+ private
62
+
63
+ # Return true or false, depending on whether the attribute_definitions on the model
64
+ # meet the specification of the Aws Sdk
65
+ # This is a syntax, not a logic check
66
+ def attribute_definitions_meet_spec?
67
+ attribute_definitions.each do |definition|
68
+ return false unless attribute_definition_meets_spec?(definition)
69
+ end
70
+ end
71
+
72
+ def attribute_definition_meets_spec?(definition)
73
+ return (definition.has_key?(:attribute_name) && \
74
+ definition.has_key?(:attribute_type) && \
75
+ definition[:attribute_name].class == String && \
76
+ definition[:attribute_type].class == String && \
77
+ ['S','N', 'B'].include?(definition[:attribute_type]))
78
+ end
79
+
80
+ def build_attribute_definition(name, key_type)
81
+ {
82
+ attribute_name: name,
83
+ attribute_type: hash_key_type(key_type)
84
+ }
85
+ end
86
+
87
+ def hash_key_type(key_type = nil)
88
+ return 'S' if key_type == String
89
+ return 'N' if key_type == Fixnum or key_type == Integer
90
+ return nil
91
+ end
92
+
93
+ def build_key_schema(name)
94
+ {
95
+ attribute_name: name,
96
+ key_type: 'HASH'
97
+ }
98
+ end
99
+
100
+ # convert values in queries to DynamoDB
101
+ # into types as expected by DynamoDB
102
+ def dyno_typed_key(key:, val:)
103
+ typed_class = self.fields[key].options[:type]
104
+ return (document_typed(klass: typed_class, value: val))
105
+ end
106
+
107
+ end
108
+ end
109
+ end
@@ -4,7 +4,13 @@ module TinyDyno
4
4
 
5
5
  def save(options = {})
6
6
  if new_record?
7
- request_put_item(options)
7
+ if request_put_item(options)
8
+ changes_applied
9
+ @new_record = nil
10
+ return true
11
+ else
12
+ return false
13
+ end
8
14
  else
9
15
  request_update_item(options)
10
16
  end
@@ -13,14 +19,8 @@ module TinyDyno
13
19
  private
14
20
 
15
21
  def request_put_item(options)
16
- request = build_put_item_request(options)
17
- if TinyDyno::Adapter.put_item(put_item_request: request)
18
- changes_applied
19
- @new_record = nil
20
- return true
21
- else
22
- return false
23
- end
22
+ request = request_as_new_record(build_item_request(options))
23
+ return(TinyDyno::Adapter.put_item(put_item_request: request))
24
24
  end
25
25
 
26
26
  # The target structure as per
@@ -51,7 +51,7 @@ module TinyDyno
51
51
  # "ExpressionAttributeValueVariable" => "value", # value <Hash,Array,String,Numeric,Boolean,IO,Set,nil>
52
52
  # },
53
53
  # })
54
- def build_put_item_request(options)
54
+ def build_item_request(options)
55
55
  {
56
56
  table_name: self.class.table_name,
57
57
  item: build_item_request_entries
File without changes
@@ -1,3 +1,3 @@
1
1
  module TinyDyno
2
- VERSION = '0.1.7'
2
+ VERSION = '0.1.9'
3
3
  end
data/lib/tiny_dyno.rb CHANGED
@@ -1,11 +1,6 @@
1
1
  require 'active_model'
2
2
  require 'aws-sdk'
3
3
 
4
- # if ENV['RACK_ENV'] == 'development'
5
- # require 'pry'
6
- # require 'awesome_print'
7
- # end
8
-
9
4
  require 'tiny_dyno/extensions'
10
5
 
11
6
  require 'tiny_dyno/version'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tiny_dyno
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Gerschner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-30 00:00:00.000000000 Z
11
+ date: 2015-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -162,6 +162,7 @@ files:
162
162
  - ".ruby-version"
163
163
  - ".simplecov"
164
164
  - ".travis.yml"
165
+ - CHANGES.md
165
166
  - Gemfile
166
167
  - Guardfile
167
168
  - LICENSE
@@ -185,14 +186,17 @@ files:
185
186
  - lib/tiny_dyno/errors/attribute_errors.rb
186
187
  - lib/tiny_dyno/errors/hash_key_errors.rb
187
188
  - lib/tiny_dyno/errors/tiny_dyno_error.rb
189
+ - lib/tiny_dyno/expected.rb
188
190
  - lib/tiny_dyno/extensions.rb
189
191
  - lib/tiny_dyno/extensions/module.rb
190
192
  - lib/tiny_dyno/fields.rb
191
193
  - lib/tiny_dyno/fields/standard.rb
194
+ - lib/tiny_dyno/hash_key.rb
192
195
  - lib/tiny_dyno/hash_keys.rb
193
196
  - lib/tiny_dyno/loggable.rb
194
197
  - lib/tiny_dyno/persistable.rb
195
198
  - lib/tiny_dyno/range_attributes.rb
199
+ - lib/tiny_dyno/range_key.rb
196
200
  - lib/tiny_dyno/stateful.rb
197
201
  - lib/tiny_dyno/tables.rb
198
202
  - lib/tiny_dyno/version.rb