dynameek 0.1.1a → 0.2.1

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.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in foo.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ dynameek (0.2.1)
5
+ aws-sdk
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ activesupport (3.2.13)
11
+ i18n (= 0.6.1)
12
+ multi_json (~> 1.0)
13
+ aws-sdk (1.8.5)
14
+ json (~> 1.4)
15
+ nokogiri (>= 1.4.4)
16
+ uuidtools (~> 2.1)
17
+ diff-lcs (1.2.1)
18
+ fake_dynamo (0.1.1)
19
+ activesupport
20
+ json
21
+ sinatra
22
+ i18n (0.6.1)
23
+ json (1.7.7)
24
+ multi_json (1.7.1)
25
+ nokogiri (1.5.8)
26
+ rack (1.5.2)
27
+ rack-protection (1.5.0)
28
+ rack
29
+ rspec (2.13.0)
30
+ rspec-core (~> 2.13.0)
31
+ rspec-expectations (~> 2.13.0)
32
+ rspec-mocks (~> 2.13.0)
33
+ rspec-core (2.13.1)
34
+ rspec-expectations (2.13.0)
35
+ diff-lcs (>= 1.1.3, < 2.0)
36
+ rspec-mocks (2.13.0)
37
+ sinatra (1.4.1)
38
+ rack (~> 1.5, >= 1.5.2)
39
+ rack-protection (~> 1.4)
40
+ tilt (~> 1.3, >= 1.3.4)
41
+ tilt (1.3.6)
42
+ uuidtools (2.1.3)
43
+
44
+ PLATFORMS
45
+ ruby
46
+
47
+ DEPENDENCIES
48
+ dynameek!
49
+ fake_dynamo
50
+ rspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Max Dupenois
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # Dynameek
2
+ A very lightweight ORMish model thing for amazon's dynamo db, after initialising the aws-sdk with something like:
3
+
4
+ amazon_config_path = File.join(File.dirname(__FILE__), *%w[.. config amazon.config.yml])
5
+ amazon_config = YAML.load(File.read(amazon_config_path))
6
+ AWS.config(amazon_config[ENVIRONMENT])
7
+
8
+ ##Models
9
+
10
+ You can create table models with this kind of syntax:
11
+
12
+ class Conversion < Dynameek::Model
13
+
14
+ field :client_id, :integer
15
+ field :channel_id, :string
16
+ field :goal_name, :string
17
+ field :time, :datetime
18
+
19
+ multi_column_hash_key [:client_id, :channel_id]
20
+ range :time
21
+
22
+ end
23
+
24
+ Creation of the models is as you'd expect
25
+
26
+ con = Conversion.create(:client_id => 1, :channel_id => "google", :goal_name=> "Some Goal", :time => DateTime.now)
27
+
28
+ The models can be edited like normal (_no update\_attributes yet though_)
29
+
30
+ con.goal_name="hello"
31
+ con.save
32
+
33
+ These models can be queried by find and query, although this is still undergoing some refactoring at the moment it currently looks something like this:
34
+
35
+ Conversion.find([1, "google"], DateTime.new([Some existing datetime]))
36
+
37
+ Conversion.query(["1", "google"]).where(DateTime.now, :lt).where(DateTime.now - 10, :gte).all
38
+
39
+ NB. The where clauses are only for referencing the range part of the composite hash key, there is currently no way to search by
40
+ hash contents as that felt like it was against the point of a document store.
41
+
42
+ ### Disclaimery Bit
43
+
44
+ Delete is not currently supported because I don't need it. The gem is dynameek (unsurprisingly) but I wouldn't use it yet, far better
45
+ to clone down the project and modify it for your own use.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/dynameek.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dynameek/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "dynameek"
8
+ gem.version = Dynameek::VERSION
9
+ gem.authors = ["Max Dupenois"]
10
+ gem.email = ["max.dupenois@forward.co.uk"]
11
+ gem.description = %q{A very lightweight model for DynamoDB tables in, certainly not in a finished state}
12
+ gem.summary = %q{Dynameek - A dynamodb model}
13
+ gem.homepage = "http://github.com/maxdupenois/dynameek"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency("aws-sdk")
21
+ gem.add_development_dependency("rspec")
22
+ gem.add_development_dependency("fake_dynamo")
23
+ end
@@ -30,10 +30,11 @@ module Dynameek
30
30
 
31
31
  def build!
32
32
  return if dynamo_db.tables[table_name].exists?
33
- new_table = dynamo_db.tables.create(table_name, @@read_write[0], @@read_write[1],
34
- :hash_key => { hash_key_field.field => hash_key_field.type },
35
- :range_key => { range_field.field => range_field.type == :datetime ? :number : range_field.type }
36
- )
33
+ opts = {:hash_key => { hash_key_info.field => [:datetime, :integer, :float].include?(hash_key_info.type) ? :number : hash_key_info.type }}
34
+ if range?
35
+ opts[:range_key] = { range_info.field => [:datetime, :integer, :float].include?(range_info.type) ? :number : range_info.type }
36
+ end
37
+ new_table = dynamo_db.tables.create(table_name, read_units, write_units, opts)
37
38
  puts "Creating table, this may take a few minutes"
38
39
  while new_table.status == :creating
39
40
  sleep 1
@@ -17,21 +17,29 @@ module Dynameek
17
17
  end
18
18
 
19
19
  def where(value, op=:eq)
20
- raise Exception("Op #{op.to_s} not recognised") if(!@range.keys.include?(op))
20
+ raise Exception.new("Op #{op.to_s} not recognised") if(!@range.keys.include?(op))
21
21
  @range[op] = value
22
22
  self
23
23
  end
24
24
 
25
+ def delete
26
+ each(&:delete)
27
+ end
28
+
25
29
  def all
26
30
  run
27
31
  end
28
32
 
29
33
  def each
30
- all.each
34
+ all.each do |item|
35
+ yield(item)
36
+ end
31
37
  end
32
38
 
33
39
  def each_with_index
34
- all.each_with_index
40
+ all.each_with_index do |item, index|
41
+ yield(item, index)
42
+ end
35
43
  end
36
44
 
37
45
  RANGE_QUERY_MAP =
@@ -51,22 +59,29 @@ module Dynameek
51
59
  hash_key = @hash_key
52
60
  hash_key = hash_key.join(@model.multi_column_join) if(hash_key.is_a?(Array))
53
61
 
54
- query_hash = {:hash_value => hash_key}
62
+ query_hash = {:hash_value => hash_key, :select => :all}
55
63
 
56
64
  query_hash = @range.reduce(query_hash) do |hsh, (key, val)|
57
65
  if(!val.nil?)
58
- hsh[RANGE_QUERY_MAP[key]] = @model.convert_to_dynamodb(@model.range_field.type, val)
66
+ hsh[RANGE_QUERY_MAP[key]] = @model.convert_to_dynamodb(@model.range_info.type, val)
59
67
  end
60
68
  hsh
61
69
  end
62
- @model.table.items.query(query_hash).map{|item| @model.item_to_instance(item)}
70
+ # p query_hash
71
+ # "CONTENTS"
72
+ # @model.table.items.each{|item| p item.inspect}
73
+ # p "_________"
74
+ @model.table.items.query(query_hash).map{|item|
75
+ # p item.inspect
76
+ @model.item_to_instance(item)
77
+ }
63
78
 
64
79
  end
65
80
 
66
81
 
67
82
  end
68
83
 
69
- [:query, :where, :all, :each, :each_with_index].each do |method|
84
+ [:query, :where, :all, :each, :each_with_index, :delete].each do |method|
70
85
  define_method(method) do |*args|
71
86
  qc = QueryChain.new(self)
72
87
  args = [] if !args
@@ -1,26 +1,70 @@
1
1
  module Dynameek
2
2
  module Model
3
3
  module Structure
4
-
5
- @fields = {}
6
- @hash_key = OpenStruct.new
7
- @hash_key.field = nil
8
- @hash_key.type = nil
9
-
10
- @range = OpenStruct.new
11
- @range.field = nil
12
- @range.type = nil
13
-
14
- @read_write = [10, 5]
4
+
15
5
 
16
- @multi_column_hash_key_fields = []
17
- @multi_column_join = "|"
18
-
6
+ def fields
7
+ @fields ||= {}
8
+ end
9
+
10
+ def hash_key_info
11
+ if(@hash_key.nil?)
12
+ @hash_key = OpenStruct.new
13
+ @hash_key.field = nil
14
+ @hash_key.type = nil
15
+ end
16
+ @hash_key
17
+ end
18
+
19
+ def range_info
20
+ if(@range.nil?)
21
+ @range = OpenStruct.new
22
+ @range.field = nil
23
+ @range.type = nil
24
+ end
25
+ @range
26
+ end
27
+
28
+ def range?
29
+ !range_info.field.nil?
30
+ end
31
+
32
+ def read_units
33
+ @read_write ||= [10, 5]
34
+ @read_write[0]
35
+ end
36
+
37
+ def write_units
38
+ @read_write ||= [10, 5]
39
+ @read_write[1]
40
+ end
41
+
42
+ def read_write(vals)
43
+ @read_write = vals
44
+ end
45
+
46
+ def multi_column_hash_key_fields
47
+ @multi_column_hash_key_fields ||= []
48
+ end
49
+
50
+
51
+
52
+ def multi_column_join
53
+ @multi_column_join ||= "|"
54
+ end
55
+
56
+ def multi_column_join=(join)
57
+ @multi_column_join =join
58
+ end
59
+
60
+ def multi_column_hash_key?
61
+ !multi_column_hash_key_fields.empty?
62
+ end
19
63
 
20
64
  def field fieldname, type
21
65
  fieldname = fieldname.to_sym
22
66
  type = type.to_sym
23
- @fields[fieldname] = type
67
+ fields[fieldname] = type
24
68
  define_method(fieldname.to_s) { read_attribute(fieldname) }
25
69
  define_method("#{fieldname.to_s}?") { !read_attribute(fieldname).nil? }
26
70
  define_method("#{fieldname.to_s}=") {|value| write_attribute(fieldname, value) }
@@ -31,74 +75,48 @@ module Dynameek
31
75
  def hash_key fieldname
32
76
  fieldname = fieldname.to_sym
33
77
  check_field(fieldname)
34
- @hash_key.field = fieldname
35
- @hash_key.type = @fields[fieldname]
78
+ hash_key_info.field = fieldname
79
+ hash_key_info.type = fields[fieldname]
36
80
  define_method(:hash_key) { read_attribute(fieldname) }
37
81
  end
38
82
 
39
- def multi_column_join
40
- @multi_column_join
41
- end
42
- def multi_column_join=(join)
43
- @multi_column_join = join
44
- end
45
- def multi_column_hash_key?
46
- !@multi_column_hash_key_fields.empty?
47
- end
83
+
48
84
 
49
85
 
50
86
 
51
87
  def multi_column_hash_key fieldnames
52
- fields = fieldnames.map(&:to_sym)
53
- fields.each{|f| check_field(f)}
54
- @multi_column_hash_key_fields = fields
55
- fieldname = fieldnames.map(&:to_s).join("_").to_s
56
- @fields[fieldname] = :string
88
+ fieldnames = fieldnames.map(&:to_sym)
89
+ fieldnames.each{|f| check_field(f)}
90
+ fieldnames.each {|f| multi_column_hash_key_fields << f}
91
+ fieldname = fieldnames.map(&:to_s).join("_").to_sym
92
+ fields[fieldname] = :string
57
93
  define_method(:hash_key) do
58
- @multi_column_hash_key_fields.reduce([]) do |memo, field|
94
+ self.class.multi_column_hash_key_fields.reduce([]) do |memo, field|
59
95
  memo << attributes[field]
60
96
  memo
61
- end.join(@multi_column_join)
97
+ end.join(self.class.multi_column_join)
62
98
  end
63
99
  alias_method fieldname, :hash_key
64
- @hash_key.field = fieldname
65
- @hash_key.type = :string
100
+ hash_key_info.field = fieldname
101
+ hash_key_info.type = :string
66
102
  end
67
103
 
68
- def hash_key_field
69
- @hash_key
70
- end
71
104
 
72
105
 
73
106
  def range fieldname
74
107
  fieldname = fieldname.to_sym
75
108
  check_field(fieldname)
76
- @range.field = fieldname
77
- @range.type = @fields[fieldname]
109
+ range_info.field = fieldname
110
+ range_info.type = fields[fieldname]
78
111
  end
79
112
 
80
113
 
81
- def read_write read, write
82
- @read_write = [read, write]
83
- end
84
114
 
85
- def read_units
86
- @read_write[0]
87
- end
88
- def write_units
89
- @read_write[1]
90
- end
91
-
92
- def fields
93
- @fields
94
- end
95
-
96
- def range_field
97
- @range.field.nil? ? nil : @range
98
- end
115
+
116
+
99
117
 
100
118
  def check_field(fieldname)
101
- raise Exception("#{fieldname} is not a recognised field") if @fields[fieldname].nil?
119
+ raise ("#{fieldname} is not a recognised field") if fields[fieldname].nil?
102
120
  end
103
121
 
104
122
  end
@@ -1,95 +1,132 @@
1
- class Dynameek::Model
2
- extend Dynameek::Model::DynamoDb
3
- extend Dynameek::Model::Structure
4
- extend Dynameek::Model::Query
5
-
6
-
7
-
8
-
9
- attr_accessor :attributes
10
-
11
-
12
-
13
- def self.find(hash_key, range_val=nil)
14
- raise Exception("This has a composite hash with a range, the range val is required") if(range_val.nil? && !range_field.field.nil?)
15
- #multicolumn
16
- hash_key = hash_key.join(multi_column_join) if(hash_key.is_a?(Array))
17
-
18
- items = if !range_val.nil?
19
- range_val = convert_to_dynamodb(range_field.type, range_val)
20
- table.batch_get(:all, [[hash_key, range_val]])
21
- else
22
- table.batch_get(:all, [hash_key])
1
+ module Dynameek
2
+ module Model
3
+ def self.included(base)
4
+ base.extend ClassMethods
23
5
  end
24
- # p items.methods - Object.new.methods
25
- return nil if(items.entries.size == 0)
26
- item_to_instance(items.first)
27
6
 
28
- end
29
-
7
+ def save
8
+ attribs = self.class.fields.reduce({}) do |memo, (field, type)|
9
+ #Always call the read method in case it has been overwritten
10
+ #Note that this is required for the multicolumn key
11
+ val = self.send field
12
+ val = self.class.convert_to_dynamodb(type, val)
13
+ memo[field] = val
14
+ memo
15
+ end
16
+ self.class.before_save_callbacks.each{|method| self.send method}
17
+ self.class.table.batch_write(
18
+ :put => [
19
+ attribs
20
+ ]
21
+ )
22
+ self
23
+ end
24
+
25
+
26
+
27
+ def attributes
28
+ @attributes ||= {}
29
+ end
30
+
31
+ def read_attribute(fieldname)
32
+ attributes[fieldname]
33
+ end
30
34
 
31
-
32
- def self.item_to_instance(item)
33
- item = item.attributes if item.is_a?(AWS::DynamoDB::Item)
34
- instance = self.new
35
- fields.each do |field, type|
36
- next if multi_column_hash_key? && field == hash_key_field.field
37
- instance.send "#{field.to_s}=", convert_from_dynamodb(type, item[field.to_s])
35
+ def write_attribute(fieldname, value)
36
+ attributes[fieldname] = value
37
+ end
38
+
39
+ def delete
40
+ if self.class.range?
41
+ range_val = self.class.convert_to_dynamodb(self.class.range_info.type, self.send(self.class.range_info.field))
42
+ #Rounding errors can be irritating here so if we have the actual item we'll use it's range_val, nope that makes things worse
43
+ # range_val = dynamo_item.range_value if !dynamo_item.nil?
44
+ # p "TRYING TO DELETE #{[[hash_key, range_val]]}.inspect"
45
+ # p "FINDING THAT THING: #{self.class.find(hash_key, self.send(self.class.range_info.field)).inspect}"
46
+ # p "VIA BATCH GET #{self.class.table.batch_get(:all, [[hash_key, range_val]]).entries.inspect}"
47
+ self.class.table.batch_delete([[hash_key, range_val]])
48
+ else
49
+ self.class.table.batch_delete([hash_key])
50
+ end
51
+ end
52
+
53
+ def dynamo_item
54
+ @dynamo_item ||= nil
38
55
  end
39
- instance
40
- end
41
-
42
56
 
43
-
44
- def self.create(attrib)
45
- instance = self.new
46
- attrib.each do |key, val|
47
- instance.send "#{key.to_s}=", val
57
+ def dynamo_item=(item)
58
+ @dynamo_item = item
48
59
  end
49
- instance.save
50
- end
51
60
 
52
- def self.before_save_callbacks
53
- @before_save_callbacks ||= Set.new
54
- end
61
+ module ClassMethods
62
+ include Dynameek::Model::DynamoDb
63
+ include Dynameek::Model::Structure
64
+ include Dynameek::Model::Query
65
+
55
66
 
56
- def self.before_save method
57
- before_save_callbacks << method.to_sym
58
- end
59
67
 
60
- def save
61
- attribs = self.class.fields.reduce({}) do |memo, (field, type)|
62
- #Always call the read method in case it has been overwritten
63
- #Note that this is required for the multicolumn key
64
- val = self.send field
65
- val = self.class.convert_to_dynamodb(type, val)
66
- memo[field] = val
67
- memo
68
- end
69
- self.class.before_save_callbacks.each{|method| self.send method}
70
- self.class.table.batch_write(
71
- :put => [
72
- attribs
73
- ]
74
- )
75
- self
76
- end
68
+
69
+ def find(hash_key, range_val=nil)
70
+ raise Exception("This has a composite hash with a range, the range val is required") if(range_val.nil? && range?)
71
+ #multicolumn
72
+ hash_key = hash_key.join(multi_column_join) if(hash_key.is_a?(Array))
77
73
 
74
+ items = if range?
75
+ range_val = convert_to_dynamodb(range_info.type, range_val)
76
+ table.batch_get(:all, [[hash_key, range_val]])
77
+ else
78
+ table.batch_get(:all, [hash_key])
79
+ end
80
+ # p items.methods - Object.new.methods
81
+ return nil if(items.entries.size == 0)
82
+ item_to_instance(items.first)
83
+
84
+ end
78
85
 
79
- def self.table_name
80
- self.to_s
81
- end
86
+ def delete_table
87
+ table.delete
88
+ end
89
+
82
90
 
83
- private
91
+ def item_to_instance(item)
92
+ item_hsh = (item.is_a?(AWS::DynamoDB::Item) || item.is_a?(AWS::DynamoDB::ItemData) ? item.attributes.to_hash : item)
93
+ instance = self.new
94
+ fields.each do |field, type|
95
+ next if multi_column_hash_key? && field == hash_key_info.field
96
+ instance.send "#{field.to_s}=", convert_from_dynamodb(type, item_hsh[field.to_s])
97
+ end
98
+ if item.is_a?(AWS::DynamoDB::Item) || item.is_a?(AWS::DynamoDB::ItemData)
99
+ instance.dynamo_item = item.is_a?(AWS::DynamoDB::ItemData) ? item.item : item
100
+ end
101
+ instance
102
+ end
103
+
104
+
105
+
106
+ def create(attrib)
107
+ instance = self.new
108
+ attrib.each do |key, val|
109
+ instance.send "#{key.to_s}=", val
110
+ end
111
+ instance.save
112
+ end
113
+
114
+ def before_save_callbacks
115
+ @before_save_callbacks ||= Set.new
116
+ end
117
+
118
+ def before_save method
119
+ before_save_callbacks << method.to_sym
120
+ end
84
121
 
85
- def read_attribute(fieldname)
86
- @attributes[fieldname]
87
- end
88
122
 
89
- def write_attribute(fieldname, value)
90
- @attributes = {} if(!@attributes)
91
- @attributes[fieldname] = value
92
- end
123
+
124
+ def table_name
125
+ self.to_s
126
+ end
127
+
93
128
 
94
129
 
130
+ end
131
+ end
95
132
  end
@@ -0,0 +1,3 @@
1
+ module Dynameek
2
+ VERSION = "0.2.1"
3
+ end
data/lib/dynameek.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require File.join(File.dirname(__FILE__), *%w[dynameek version])
2
+ require 'ostruct'
3
+
1
4
  module Dynameek
2
5
  end
3
6
 
@@ -0,0 +1,13 @@
1
+ class Conversion
2
+ include Dynameek::Model
3
+
4
+ field :client_id, :integer
5
+ field :channel_id, :string
6
+ field :goal_name, :string
7
+ field :time, :datetime
8
+
9
+ multi_column_hash_key [:client_id, :channel_id]
10
+ range :time
11
+
12
+
13
+ end
@@ -0,0 +1,13 @@
1
+ class Simple
2
+ include Dynameek::Model
3
+
4
+
5
+ field :my_id, :integer
6
+ field :some_value, :string
7
+
8
+
9
+ hash_key :my_id
10
+
11
+
12
+
13
+ end
@@ -0,0 +1,58 @@
1
+ require File.join(File.dirname(__FILE__), *%w[spec_helper])
2
+
3
+ describe Conversion do
4
+ before(:all) do
5
+ Conversion.delete_table
6
+ end
7
+ before(:each) do
8
+ Conversion.query([1, "google"]).delete
9
+ end
10
+
11
+ it "should allow you to create a new conversion" do
12
+ con = nil
13
+ lambda{
14
+ con = Conversion.create(:client_id => 1, :channel_id => "google", :goal_name=> "new conversion", :time => DateTime.now)
15
+ }.should_not raise_error
16
+ con.hash_key.should == "1|google"
17
+ end
18
+
19
+
20
+ it "should allow you to find a conversion" do
21
+ now = DateTime.now
22
+ Conversion.create(:client_id => 1, :channel_id => "google", :goal_name=> "find conversion", :time => now)
23
+ con = Conversion.find([1, "google"], now)
24
+ con.should_not be_nil
25
+ con.hash_key.should == "1|google"
26
+ end
27
+
28
+
29
+ it "should allow you to delete a range" do
30
+ now = DateTime.now
31
+ Conversion.create(:client_id => 1, :channel_id => "google", :goal_name=> "delete conversion", :time => now)
32
+ Conversion.query([1, "google"]).all.size.should == 1
33
+ Conversion.query([1, "google"]).delete
34
+ Conversion.query([1, "google"]).all.size.should == 0
35
+ end
36
+
37
+ it "should allow you to find a query a conversion" do
38
+ now = DateTime.now
39
+ Conversion.create(:client_id => 1, :channel_id => "google", :goal_name=> "Some Goal", :time => now)
40
+ cons = Conversion.query([1, "google"]).all
41
+ cons.size.should == 1
42
+ end
43
+
44
+ it "should allow you to find a query a conversion within a range" do
45
+ now = DateTime.now
46
+ Conversion.create(:client_id => 1, :channel_id => "google", :goal_name=> "Some Goal", :time => now - 3)
47
+ Conversion.create(:client_id => 1, :channel_id => "google", :goal_name=> "Some Goal", :time => now - 2)
48
+ Conversion.create(:client_id => 1, :channel_id => "google", :goal_name=> "Some Goal", :time => now - 1)
49
+ cons = Conversion.query([1, "google"]).where(now, :lt).all
50
+ cons.size.should == 3
51
+ cons = Conversion.query([1, "google"]).where(now - 4, :gt).all
52
+ cons.size.should == 3
53
+ # cons = Conversion.query([1, "google"]).where(now - 2, :gte).where(now, :lt).all
54
+ # cons.size.should == 2 Not supported on fake_dynamo, seems to work fine on prod
55
+ end
56
+
57
+
58
+ end
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__), *%w[spec_helper])
2
+
3
+ describe Simple do
4
+ before(:all) do
5
+ Simple.delete_table
6
+ end
7
+ before(:each) do
8
+ simple = Simple.find(1)
9
+ simple.delete if(!simple.nil?)
10
+ end
11
+ it "should allow you to create a new simple" do
12
+ con = nil
13
+ lambda{
14
+ con = Simple.create(:my_id => 1, :some_value => "hello")
15
+ }.should_not raise_error
16
+ con.hash_key.should == 1
17
+ con.some_value.should == "hello"
18
+ end
19
+ it "should allow you to find a created simple" do
20
+ Simple.create(:my_id => 1, :some_value => "hello")
21
+ con = Simple.find(1)
22
+ con.hash_key.should == 1
23
+ con.some_value.should == "hello"
24
+ end
25
+
26
+ end
@@ -0,0 +1,13 @@
1
+ require 'rspec'
2
+ require 'aws-sdk'
3
+
4
+ require File.join(File.dirname(__FILE__), *%w[.. .. lib dynameek])
5
+
6
+ AWS.config(:use_ssl => false,
7
+ :dynamo_db_endpoint => 'localhost',
8
+ :dynamo_db_port => 4567,
9
+ :access_key_id => "xxx",
10
+ :secret_access_key => "xxx")
11
+
12
+ require File.join(File.dirname(__FILE__), *%w[.. models conversion])
13
+ require File.join(File.dirname(__FILE__), *%w[.. models simple])
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynameek
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: 5
5
- version: 0.1.1a
4
+ prerelease:
5
+ version: 0.2.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Max Dupenois
@@ -11,10 +11,43 @@ bindir: bin
11
11
  cert_chain: []
12
12
 
13
13
  date: 2013-03-20 00:00:00 Z
14
- dependencies: []
15
-
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: aws-sdk
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: rspec
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :development
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: fake_dynamo
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id003
16
48
  description: A very lightweight model for DynamoDB tables in, certainly not in a finished state
17
- email: max.dupenois@forward.co.uk
49
+ email:
50
+ - max.dupenois@forward.co.uk
18
51
  executables: []
19
52
 
20
53
  extensions: []
@@ -22,11 +55,23 @@ extensions: []
22
55
  extra_rdoc_files: []
23
56
 
24
57
  files:
58
+ - Gemfile
59
+ - Gemfile.lock
60
+ - LICENSE.txt
61
+ - README.md
62
+ - Rakefile
63
+ - dynameek.gemspec
64
+ - lib/dynameek.rb
65
+ - lib/dynameek/model.rb
25
66
  - lib/dynameek/model/dynamo_db.rb
26
67
  - lib/dynameek/model/query.rb
27
68
  - lib/dynameek/model/structure.rb
28
- - lib/dynameek/model.rb
29
- - lib/dynameek.rb
69
+ - lib/dynameek/version.rb
70
+ - test/models/conversion.rb
71
+ - test/models/simple.rb
72
+ - test/spec/conversion_spec.rb
73
+ - test/spec/simple_spec.rb
74
+ - test/spec/spec_helper.rb
30
75
  homepage: http://github.com/maxdupenois/dynameek
31
76
  licenses: []
32
77
 
@@ -44,15 +89,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
44
89
  required_rubygems_version: !ruby/object:Gem::Requirement
45
90
  none: false
46
91
  requirements:
47
- - - ">"
92
+ - - ">="
48
93
  - !ruby/object:Gem::Version
49
- version: 1.3.1
94
+ version: "0"
50
95
  requirements: []
51
96
 
52
97
  rubyforge_project:
53
98
  rubygems_version: 1.8.24
54
99
  signing_key:
55
100
  specification_version: 3
56
- summary: Dynameek
57
- test_files: []
58
-
101
+ summary: Dynameek - A dynamodb model
102
+ test_files:
103
+ - test/models/conversion.rb
104
+ - test/models/simple.rb
105
+ - test/spec/conversion_spec.rb
106
+ - test/spec/simple_spec.rb
107
+ - test/spec/spec_helper.rb