ork 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d614293fd63e1d8d2a8de96cfb92ad40c09ebdc5
4
+ data.tar.gz: f487220a7969011adfe79399feb8ddcecc0d7187
5
+ SHA512:
6
+ metadata.gz: 39953ee12661946b11f55e278253d8726871ff9b8d3eb3c389e9d2ba447460f8c959048c99b9d6ade5a7992974297bc7bc78d8b55ba0e7c9366c82b6492fb9ba
7
+ data.tar.gz: 7b565b3a8ff7901cc7457464a335a54b0c5c1a1f53cf159f87815e4402a250d168bbd275da6f7a4a12a8621c59be86e53e08cf5066e10c9eb5428ea632a6cc03
data/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # `ork`
2
+ [![Gem Version](https://badge.fury.io/rb/ork.png)](http://badge.fury.io/rb/ork)
3
+ [![Build Status](https://secure.travis-ci.org/eMancu/ork.png)](http://travis-ci.org/eMancu/ork)
4
+ [![Code Climate](https://codeclimate.com/github/eMancu/ork.png)](https://codeclimate.com/github/eMancu/ork)
5
+ [![Coverage Status](https://coveralls.io/repos/eMancu/ork/badge.png)](https://coveralls.io/r/eMancu/ork)
6
+ [![Dependency Status](https://gemnasium.com/eMancu/ork.png)](https://gemnasium.com/eMancu/ork)
7
+
8
+ `ork` is a small Ruby modeling layer for **Riak**, Basho's distributed database inspired by [Ohm](http://ohm.keyvalue.org).
9
+
10
+ ## Dependencies
11
+
12
+ `ork` requires Ruby 1.9 or later and the `riak-client` gem to connect to **Riak**.
13
+
14
+ ## Getting started
15
+
16
+ ## Attributes
17
+
18
+ Ork::Model provides one attribute type:
19
+
20
+ - Ork::Model.attribute attribute
21
+
22
+ And three meta types:
23
+
24
+ - Ork::Model.reference reference
25
+ - Ork::Model.referenced referenced
26
+ - Ork::Model.collection collection
27
+
28
+ ### attribute
29
+
30
+ An `attribute` is just any value that can be stored.
31
+
32
+ ### reference
33
+
34
+ It's a special kind of attribute that references another model.
35
+ Internally, Ork will keep a pointer to the model (its ID), but you get
36
+ accessors that give you real instances. You can think of it as the model
37
+ containing the foreign key to another model.
38
+
39
+ ### referenced
40
+
41
+ Provides an accessor to search for _one_ model that `reference` the current model.
42
+
43
+ ### collection
44
+
45
+ Provides an accessor to search for _all_ models that `reference` the current model.
@@ -0,0 +1,28 @@
1
+ module Ork
2
+ class Connection
3
+ attr_accessor :context, :options
4
+
5
+ def initialize(context = :main, options = {})
6
+ @context = context
7
+ @options = options
8
+ end
9
+
10
+ def reset!
11
+ threaded[context] = nil
12
+ end
13
+
14
+ def start(context, options = {})
15
+ self.context = context
16
+ self.options = options
17
+ self.reset!
18
+ end
19
+
20
+ def riak
21
+ threaded[context] ||= Riak::Client.new(options)
22
+ end
23
+
24
+ def threaded
25
+ Thread.current[:ork] ||= {}
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,138 @@
1
+ module Ork::Model
2
+ module Associations
3
+ # A macro for defining an attribute, an index, and an accessor
4
+ # for a given model.
5
+ #
6
+ # Example:
7
+ #
8
+ # class Post
9
+ # include Ork::Model
10
+ #
11
+ # reference :user, :User
12
+ # end
13
+ #
14
+ # # It's the same as:
15
+ #
16
+ # class Post
17
+ # include Ork::Model
18
+ #
19
+ # attribute :user_id
20
+ # index :user_id
21
+ #
22
+ # def user
23
+ # @_memo[:user] ||= User[user_id]
24
+ # end
25
+ #
26
+ # def user=(user)
27
+ # self.user_id = user.id
28
+ # @_memo[:user] = user
29
+ # end
30
+ #
31
+ # def user_id=(user_id)
32
+ # @_memo.delete(:user_id)
33
+ # self.user_id = user_id
34
+ # end
35
+ # end
36
+ #
37
+ def reference(name, model)
38
+ reader = :"#{name}_id"
39
+ writer = :"#{name}_id="
40
+
41
+ index reader
42
+
43
+ define_method(reader) do
44
+ @attributes[reader]
45
+ end
46
+
47
+ define_method(writer) do |value|
48
+ @_memo.delete(name)
49
+ @attributes[reader] = value
50
+ end
51
+
52
+ define_method(:"#{name}=") do |value|
53
+ @_memo.delete(name)
54
+ send(writer, value ? value.id : nil)
55
+ end
56
+
57
+ define_method(name) do
58
+ @_memo[name] ||= begin
59
+ model = Ork::Utils.const(self.class, model)
60
+ model[send(reader)]
61
+ end
62
+ end
63
+ end
64
+
65
+ # A macro for defining a method which basically does a find.
66
+ #
67
+ # Example:
68
+ # class Post
69
+ # include Ork::Model
70
+ #
71
+ # reference :user, :User
72
+ # end
73
+ #
74
+ # class User
75
+ # include Ork::Model
76
+ #
77
+ # referenced :post, :Post
78
+ # end
79
+ #
80
+ # # is the same as
81
+ #
82
+ # class User
83
+ # include Ork::Model
84
+ #
85
+ # def post
86
+ # Post.find(:user_id => self.id)
87
+ # end
88
+ # end
89
+ #
90
+ def referenced(name, model, reference = to_reference)
91
+ define_method name do
92
+ model = Ork::Utils.const(self.class, model)
93
+ model.find(:"#{reference}_id" => id).first
94
+ end
95
+ end
96
+
97
+ # A macro for defining a method which basically does a find.
98
+ #
99
+ # Example:
100
+ # class Post
101
+ # include Ork::Model
102
+ #
103
+ # reference :user, :User
104
+ # end
105
+ #
106
+ # class User
107
+ # include Ork::Model
108
+ #
109
+ # collection :posts, :Post
110
+ # end
111
+ #
112
+ # # is the same as
113
+ #
114
+ # class User
115
+ # include Ork::Model
116
+ #
117
+ # def posts
118
+ # Post.find(:user_id => self.id)
119
+ # end
120
+ # end
121
+ #
122
+ def collection(name, model, reference = to_reference)
123
+ define_method name do
124
+ model = Ork::Utils.const(self.class, model)
125
+ model.find(:"#{reference}_id" => id)
126
+ end
127
+ end
128
+
129
+ private
130
+
131
+ def to_reference
132
+ name.to_s.
133
+ match(/^(?:.*::)*(.*)$/)[1].
134
+ gsub(/([a-z\d])([A-Z])/, '\1_\2').
135
+ downcase.to_sym
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,89 @@
1
+ module Ork::Model
2
+ module ClassMethods
3
+ attr_writer :bucket_name
4
+
5
+ # Syntactic sugar for Model.new(atts).save
6
+ def create(atts = {})
7
+ new(atts).save
8
+ end
9
+
10
+ def attributes
11
+ @attributes ||= []
12
+ end
13
+
14
+ def bucket
15
+ Ork.riak.bucket(bucket_name)
16
+ end
17
+
18
+ def bucket_name
19
+ @bucket_name ||= self.to_s.downcase
20
+ end
21
+
22
+ def indices
23
+ @indices ||= []
24
+ end
25
+
26
+ def uniques
27
+ @uniques ||= []
28
+ end
29
+
30
+ protected
31
+
32
+ # Declares persisted attributes.
33
+ # All attributes are stored on the Riak hash.
34
+ #
35
+ # Example:
36
+ # class User
37
+ # include Ork::Model
38
+ #
39
+ # attribute :name
40
+ # end
41
+ #
42
+ # # It's the same as:
43
+ #
44
+ # class User
45
+ # include Ork::Model
46
+ #
47
+ # def name
48
+ # @attributes[:name]
49
+ # end
50
+ #
51
+ # def name=(name)
52
+ # @attributes[:name] = name
53
+ # end
54
+ # end
55
+ #
56
+ def attribute(name, cast = nil)
57
+ attributes << name unless attributes.include?(name)
58
+
59
+ if cast
60
+ define_method(name) do
61
+ cast[@attributes[name]]
62
+ end
63
+ else
64
+ define_method(name) do
65
+ @attributes[name]
66
+ end
67
+ end
68
+
69
+ define_method(:"#{name}=") do |value|
70
+ @attributes[name] = value
71
+ end
72
+ end
73
+
74
+ # Index any method on your model. Once you index a method, you can
75
+ # use it in `find` statements.
76
+ def index(attribute)
77
+ indices << attribute unless indices.include?(attribute)
78
+ end
79
+
80
+ # Create a unique index for any method on your model.
81
+ #
82
+ # Note: if there is a conflict while saving, an
83
+ # `Ork::UniqueIndexViolation` violation is raised.
84
+ #
85
+ def unique(attribute)
86
+ uniques << attribute unless uniques.include?(attribute)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,44 @@
1
+ module Ork::Model
2
+ module Finders
3
+
4
+ # Retrieve a record by ID.
5
+ #
6
+ # Example:
7
+ #
8
+ # u = User.create
9
+ # u == User[u.id]
10
+ # # => true
11
+ #
12
+ def [](id)
13
+ new.send(:load!, id) if exist?(id)
14
+ rescue Riak::FailedRequest => e
15
+ raise e unless e.not_found?
16
+ nil
17
+ end
18
+
19
+ # Check if the ID exists.
20
+ def exist?(id)
21
+ !id.nil? && bucket.exists?(id)
22
+ end
23
+ alias :exists? :exist?
24
+
25
+ # Find all documents in the Document's bucket and return them.
26
+ # @overload list()
27
+ # Get all documents and return them in an array.
28
+ # @param [Hash] options options to be passed to the
29
+ # underlying {Bucket#keys} method.
30
+ # @return [Array<Document>] all found documents in the bucket
31
+ #
32
+ # @Note: This operation is incredibly expensive and should not
33
+ # be used in production applications.
34
+ #
35
+ def all
36
+ bucket.keys.inject([]) do |acc, k|
37
+ obj = self[k]
38
+ obj ? acc << obj : acc
39
+ end
40
+ end
41
+ alias :list :all
42
+
43
+ end
44
+ end
data/lib/ork/model.rb ADDED
@@ -0,0 +1,154 @@
1
+ require_relative 'model/class_methods'
2
+ require_relative 'model/associations'
3
+ require_relative 'model/finders'
4
+
5
+ module Ork
6
+ module Model
7
+ attr_reader :attributes, :id
8
+ attr_writer :id
9
+
10
+ def self.included(klass)
11
+ klass.extend(Ork::Model::ClassMethods)
12
+ klass.extend(Ork::Model::Associations)
13
+ klass.extend(Ork::Model::Finders)
14
+ end
15
+
16
+ # Initialize a model using a dictionary of attributes.
17
+ #
18
+ # Example:
19
+ #
20
+ # u = User.new(:name => "John")
21
+ #
22
+ def initialize(atts = {})
23
+ @attributes = {}
24
+ @_memo = {}
25
+ update_attributes(atts)
26
+ end
27
+
28
+ # Check for equality by doing the following assertions:
29
+ #
30
+ # 1. That the passed model is of the same type.
31
+ # 2. That they represent the same RObject id.
32
+ #
33
+ def ==(other)
34
+ other.kind_of?(model) && other.id == id
35
+ end
36
+
37
+ alias :eql? :==
38
+
39
+ def new?
40
+ !id
41
+ end
42
+
43
+ # Pretty print for the model
44
+ #
45
+ # Example:
46
+ #
47
+ # User.new(name: 'John').inspect
48
+ # # => #<User:6kS5VHNbaed9h7gFLnVg5lmO4U7 {:name=>"John"}>
49
+ def inspect
50
+ "#<#{model}:#{id || 'nil'} #{attributes.inspect}>"
51
+ end
52
+
53
+ # Update the model attributes and call save.
54
+ #
55
+ # Example:
56
+ #
57
+ # User[1].update(:name => "John")
58
+ #
59
+ # # It's the same as:
60
+ #
61
+ # u = User[1]
62
+ # u.update_attributes(:name => "John")
63
+ # u.save
64
+ #
65
+ def update(attributes)
66
+ update_attributes(attributes)
67
+ save
68
+ end
69
+
70
+ # Write the dictionary of key-value pairs to the model.
71
+ #
72
+ def update_attributes(atts)
73
+ atts.delete('_type')
74
+ atts.each { |att, val| send(:"#{att}=", val) }
75
+ end
76
+
77
+ # Delete the model
78
+ def delete
79
+ __robject.delete unless new?
80
+ freeze
81
+ rescue Riak::FailedRequest
82
+ false
83
+ end
84
+
85
+ # Persist the model attributes and update indices and unique
86
+ # indices.
87
+ #
88
+ # If the model is not valid, nil is returned. Otherwise, the
89
+ # persisted model is returned.
90
+ #
91
+ # Example:
92
+ #
93
+ # class User
94
+ # include Ork::Model
95
+ #
96
+ # attribute :name
97
+ #
98
+ # def validate
99
+ # assert_present :name
100
+ # end
101
+ # end
102
+ #
103
+ # User.new(:name => nil).save
104
+ # # => nil
105
+ #
106
+ # u = User.new(:name => "John").save
107
+ # # => #<User:6kS5VHNbaed9h7gFLnVg5lmO4U7 {:name=>"John"}>
108
+ #
109
+ def save
110
+ # FIXME: Work with validations, scrivener or hatch?
111
+ # save! if valid?
112
+ save!
113
+ end
114
+
115
+ # Saves the model without checking for validity. Refer to
116
+ # `Model#save` for more details.
117
+ def save!
118
+ __save__
119
+ end
120
+
121
+ # Preload all the attributes of this model from Riak.
122
+ def reload
123
+ new? ? self : self.load!(@id)
124
+ end
125
+
126
+ protected
127
+
128
+ def load!(id)
129
+ @id = self.__robject.key = id
130
+ @__robject = @__robject.reload(force: true)
131
+ update_attributes(@__robject.data)
132
+
133
+ self
134
+ end
135
+
136
+ # Persist the object in Riak database
137
+ def __save__
138
+ __robject.content_type = 'application/json'
139
+ __robject.data = @attributes.merge('_type' => model.name)
140
+ __robject.store
141
+ @id = __robject.key
142
+
143
+ self
144
+ end
145
+
146
+ def __robject
147
+ @__robject ||= model.bucket.new
148
+ end
149
+
150
+ def model
151
+ self.class
152
+ end
153
+ end
154
+ end
data/lib/ork/utils.rb ADDED
@@ -0,0 +1,35 @@
1
+ module Ork
2
+ # Instead of monkey patching Kernel or trying to be clever, it's
3
+ # best to confine all the helper methods in a Utils module.
4
+ module Utils
5
+
6
+ # Used by: `attribute`, `reference`, `collection`.
7
+ #
8
+ # Employed as a solution to avoid `NameError` problems when trying
9
+ # to load models referring to other models not yet loaded.
10
+ #
11
+ # Example:
12
+ #
13
+ # class Comment
14
+ # include Ork::Model
15
+ #
16
+ # reference :user, User # NameError undefined constant User.
17
+ # end
18
+ #
19
+ # Instead of relying on some clever `const_missing` hack, we can
20
+ # simply use a Symbol.
21
+ #
22
+ # class Comment
23
+ # include Ork::Model
24
+ #
25
+ # reference :user, :User
26
+ # end
27
+ #
28
+ def self.const(context, name)
29
+ case name
30
+ when Symbol then context.const_get(name)
31
+ else name
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ class Ork
2
+ VERSION = "0.0.1"
3
+ end
data/lib/ork.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'ork/connection'
2
+ require 'ork/model'
3
+ require 'ork/utils'
4
+ require "riak"
5
+
6
+ module Ork
7
+ class Error < StandardError; end
8
+
9
+ def self.conn
10
+ @conn ||= Ork::Connection.new
11
+ end
12
+
13
+ # Stores the connection options for the Riak instance.
14
+ #
15
+ # Examples:
16
+ #
17
+ # Ork.connect(:http_port => 6380, :pb_port => 15000)
18
+ #
19
+ # All of the options are simply passed on to `Riak::Client.new`.
20
+ #
21
+ def self.connect(context = :main, options = {})
22
+ conn.start(context, options)
23
+ end
24
+
25
+ # Use this if you want to do quick ad hoc riak commands against the
26
+ # defined Ork connection.
27
+ #
28
+ # Examples:
29
+ #
30
+ # Ork.riak.buckets
31
+ # Ork.riak.bucket('foo').keys
32
+ #
33
+ def self.riak
34
+ conn.riak
35
+ end
36
+ end
data/ork.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'ork'
3
+ s.version = '0.0.1'
4
+ s.date = Time.now.strftime('%Y-%m-%d')
5
+ s.summary = 'Ruby modeling layer for Riak.'
6
+ s.description = 'Ork is a small Ruby modeling layer for Riak, inspired by Ohm.'
7
+ s.authors = ['Emiliano Mancuso']
8
+ s.email = ['emiliano.mancuso@gmail.com']
9
+ s.homepage = 'http://github.com/eMancu/ork'
10
+ s.license = 'MIT'
11
+
12
+ s.files = Dir[
13
+ 'README.md',
14
+ 'rakefile',
15
+ 'lib/**/*.rb',
16
+ '*.gemspec'
17
+ ]
18
+ s.test_files = Dir['test/*.*']
19
+
20
+ s.add_dependency 'riak-client'
21
+ s.add_development_dependency 'protest'
22
+ s.add_development_dependency 'toml-rb'
23
+ end
24
+
data/rakefile ADDED
@@ -0,0 +1,31 @@
1
+ require "rake/testtask"
2
+
3
+ task :default => :test
4
+
5
+ desc 'Start riak test server'
6
+ task :start do
7
+ require File.expand_path("./test/helper", File.dirname(__FILE__))
8
+ puts '..:: Starting riak test server ::..'
9
+ test_server.start
10
+ end
11
+
12
+ desc 'Run tests'
13
+ task :test => [:start] do
14
+ Dir["test/*.rb"].each { |file| load file unless file =~ /helper.rb/ }
15
+ end
16
+
17
+ desc 'Stop riak test server'
18
+ task :stop => [:start] do
19
+ puts '..:: Stop riak test server ::..'
20
+
21
+ flush_db!
22
+ test_server.stop
23
+ end
24
+
25
+ at_exit do
26
+ puts '..:: Stop riak test server ::..'
27
+ sleep 1
28
+
29
+ flush_db!
30
+ test_server.stop
31
+ end
data/test/finders.rb ADDED
@@ -0,0 +1,43 @@
1
+ require_relative 'helper'
2
+
3
+ class Human
4
+ include Ork::Model
5
+
6
+ attribute :name
7
+ attribute :last_name
8
+
9
+ unique :name
10
+ index :last_name
11
+ end
12
+
13
+ Protest.describe 'Finders' do
14
+ setup do
15
+ @human1 = Human.create(name: 'Tony', last_name: 'Montana')
16
+ @human2 = Human.create(name: 'Cacho', last_name: 'Castaña')
17
+ end
18
+
19
+ teardown do
20
+ flush_db!
21
+ end
22
+
23
+ test 'retrieve an object by id' do
24
+ assert_equal @human1, Human[@human1.id]
25
+ end
26
+
27
+ test 'return nil when the id does not belong to an object of this bucket' do
28
+ assert_equal nil, Human['not_an_id']
29
+ end
30
+
31
+ test 'if exist an object with the id' do
32
+ assert !Human.exist?(nil)
33
+ assert !Human.exist?('not_an_id')
34
+ assert Human.exist?(@human1.id)
35
+ end
36
+
37
+ test 'list all the objects' do
38
+ assert_equal 2, Human.list.size
39
+ assert Human.list.include?(@human1)
40
+ assert Human.list.include?(@human2)
41
+ end
42
+
43
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,41 @@
1
+ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
2
+
3
+ require "rubygems"
4
+ require "protest"
5
+ require "ork"
6
+
7
+ # require 'coveralls'
8
+ # Coveralls.wear!
9
+
10
+ Riak.disable_list_keys_warnings = true
11
+
12
+ require 'riak/test_server'
13
+
14
+ def test_server
15
+ $test_server ||= begin
16
+ require 'toml'
17
+ path = File.expand_path("../test_riak_server.toml", __FILE__)
18
+ config = TOML.load_file(path, symbolize_keys: true)
19
+
20
+
21
+ server = Riak::TestServer.create(root: config[:root],
22
+ source: config[:source],
23
+ min_port: config[:min_port])
24
+
25
+
26
+ Ork.connect(:test, {
27
+ http_port: server.http_port,
28
+ pb_port: server.pb_port
29
+ })
30
+
31
+ server
32
+ rescue => e
33
+ puts ("Can't run Ork tests without the test server.\n" +
34
+ "Specify the location of your Riak installation in test/test_riak_server.toml\n" +
35
+ e.inspect)
36
+ end
37
+ end
38
+
39
+ def flush_db!
40
+ test_server.drop
41
+ end
data/test/model.rb ADDED
@@ -0,0 +1,139 @@
1
+ # encoding: UTF-8
2
+ require_relative 'helper'
3
+
4
+ class Event
5
+ include Ork::Model
6
+
7
+ attribute :name
8
+ attribute :location
9
+
10
+ unique :name
11
+ index :location
12
+ end
13
+
14
+ Protest.describe 'Ork::Model' do
15
+ context 'Definition' do
16
+ test 'have an attributes list' do
17
+ assert_equal [:name, :location], Event.attributes
18
+ end
19
+
20
+ test 'have a uniques list' do
21
+ assert_equal [:name], Event.uniques
22
+ end
23
+
24
+ test 'have an indices list' do
25
+ assert_equal [:location], Event.indices
26
+ end
27
+
28
+ test 'model owns a bucket name by default' do
29
+ assert_equal 'event', Event.bucket_name
30
+ end
31
+
32
+ test 'generate accessors for attributes' do
33
+ event = Event.new
34
+
35
+ assert event.respond_to? :name
36
+ assert event.respond_to? :name=
37
+ assert event.respond_to? :location
38
+ assert event.respond_to? :location=
39
+ end
40
+
41
+ test 'cast to different types' do
42
+ pending 'Define how to cast objects'
43
+ end
44
+
45
+ test 'model can change bucket name' do
46
+ Event.bucket_name= 'other_bucket_for_event'
47
+ assert_equal 'other_bucket_for_event', Event.bucket_name
48
+ end
49
+
50
+ test 'there is a Riak::Bucket corresponding to the model' do
51
+ assert_equal Riak::Bucket, Event.bucket.class
52
+ end
53
+ end
54
+
55
+ context 'Instance' do
56
+ setup do
57
+ @event = Event.new(name: 'Ruby')
58
+ end
59
+
60
+ test 'determine if it is a new instance or it was saved' do
61
+ assert @event.new?
62
+ @event.save
63
+ assert !@event.new?
64
+ end
65
+
66
+ test 'assign attributes from the hash' do
67
+ assert_equal 'Ruby', @event.name
68
+ end
69
+
70
+ test 'inspect a new object shows the class, attributes with id nil' do
71
+ assert_equal '#<Event:nil {:name=>"Ruby"}>', @event.inspect
72
+ end
73
+
74
+ test 'inspect a saved object shows the class, attributes with id nil' do
75
+ @event.save
76
+ assert_equal '#<Event:' + @event.id + ' {:name=>"Ruby"}>', @event.inspect
77
+ end
78
+
79
+ test 'assign an ID and save the object' do
80
+ event = Event.create(name: 'Ruby')
81
+
82
+ assert !event.new?
83
+ assert !event.id.nil?
84
+ end
85
+
86
+ test 'update and save the attributes in UTF8' do
87
+ @event.update(name: '32° Kisei-sen')
88
+ assert_equal '32° Kisei-sen', Event[@event.id].name
89
+ end
90
+
91
+ test 'update_attributes changes attributes but does not save the object' do
92
+ assert @event.new?
93
+ assert_equal 'Ruby', @event.name
94
+
95
+ @event.update_attributes(name: 'Emerald', location: 4)
96
+
97
+ assert @event.new?
98
+ assert_equal 'Emerald', @event.name
99
+ assert_equal 4, @event.location
100
+ end
101
+
102
+ context 'Deletion' do
103
+ test 'freeze the object' do
104
+ assert !@event.frozen?
105
+ @event.delete
106
+ assert @event.frozen?
107
+ end
108
+
109
+ test 'delete the object from the bucket' do
110
+ @event.save
111
+ assert Event.bucket.exist?(@event.id)
112
+ @event.delete
113
+ assert !Event.bucket.exist?(@event.id)
114
+ end
115
+ end
116
+ end
117
+
118
+ context "Equality" do
119
+ setup do
120
+ @event = Event.new(name: 'Ruby')
121
+ @other = Event.new(name: 'Emerald')
122
+ end
123
+
124
+ test 'different types' do
125
+ assert @event != 'Not an event'
126
+ end
127
+
128
+ test 'saved instances with different ids' do
129
+ @event.save
130
+ @other.save
131
+
132
+ assert @event != @other
133
+ end
134
+
135
+ test 'unsaved intances' do
136
+ pending 'Define how equality will be'
137
+ end
138
+ end
139
+ end
data/test/reference.rb ADDED
@@ -0,0 +1,73 @@
1
+ require_relative 'helper'
2
+
3
+ class Post
4
+ include Ork::Model
5
+ attribute :name
6
+ end
7
+
8
+ class Comment
9
+ include Ork::Model
10
+ attribute :text
11
+
12
+ reference :post, :Post
13
+ reference :weird_post, :Post
14
+ end
15
+
16
+ Protest.describe 'reference' do
17
+ teardown do
18
+ flush_db!
19
+ end
20
+
21
+ should 'return nil when there is no reference object' do
22
+ comment = Comment.new
23
+
24
+ assert comment.post.nil?
25
+ end
26
+
27
+ should 'raise an exception assigning an object of the wrong type' do
28
+ pending 'Not sure to support this'
29
+ assert_raise(Error) do
30
+ Comment.new post: 'Not a post'
31
+ end
32
+ end
33
+
34
+ should 'return the object referenced' do
35
+ post = Post.create name: 'New'
36
+ comment = Comment.new post: post
37
+
38
+ assert_equal post, comment.post
39
+ assert_equal post.id, comment.post_id
40
+ end
41
+
42
+ test 'object reference with not default key' do
43
+ post = Post.create name: 'New'
44
+ comment = Comment.new weird_post: post
45
+
46
+ assert_equal post, comment.weird_post
47
+ assert_equal post.id, comment.weird_post_id
48
+ end
49
+
50
+ should 'update reference to an object given the id or object' do
51
+ post = Post.create name: 'New'
52
+ comment = Comment.new
53
+
54
+ assert comment.post.nil?
55
+ assert comment.post_id.nil?
56
+
57
+ comment.post = post
58
+
59
+ assert_equal post, comment.post
60
+ assert_equal post.id, comment.post_id
61
+
62
+ post = Post.create name: 'Other'
63
+ comment.post_id = post.id
64
+
65
+ assert_equal post, comment.post
66
+ assert_equal post.id, comment.post_id
67
+ end
68
+
69
+ context 'Deletion' do
70
+ # Discuss if we want cascade all deletetion and that sort of things
71
+ end
72
+
73
+ end
@@ -0,0 +1,15 @@
1
+ # This is where the test server node will be generated. Something on
2
+ # /tmp is usually ok.
3
+ root = "/tmp/.ork_node"
4
+ min_port = 15000
5
+
6
+ # This is where Riak is installed on your system, that is, the path to
7
+ # the 'riak' and 'riak-admin' scripts. I use a self-built node, but
8
+ # here's where it will generally be on various platforms:
9
+ #
10
+ # Linux: /usr/sbin
11
+ # Solaris/OpenSolaris: /opt/riak/bin
12
+ # Mac OS/X (Homebrew): /usr/local/bin
13
+ # Source/Self built: /path/to/your/install/rel/riak/bin
14
+ #
15
+ source = "/usr/local/bin"
@@ -0,0 +1,15 @@
1
+ # This is where the test server node will be generated. Something on
2
+ # /tmp is usually ok.
3
+ root = "/tmp/.ork_node"
4
+ min_port = 15000
5
+
6
+ # This is where Riak is installed on your system, that is, the path to
7
+ # the 'riak' and 'riak-admin' scripts. I use a self-built node, but
8
+ # here's where it will generally be on various platforms:
9
+ #
10
+ # Linux: /usr/sbin
11
+ # Solaris/OpenSolaris: /opt/riak/bin
12
+ # Mac OS/X (Homebrew): /usr/local/bin
13
+ # Source/Self built: /path/to/your/install/rel/riak/bin
14
+ #
15
+ source = "/usr/local/bin"
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ork
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Emiliano Mancuso
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-07-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: riak-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: protest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: toml-rb
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Ork is a small Ruby modeling layer for Riak, inspired by Ohm.
56
+ email:
57
+ - emiliano.mancuso@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - README.md
63
+ - rakefile
64
+ - lib/ork/connection.rb
65
+ - lib/ork/model/associations.rb
66
+ - lib/ork/model/class_methods.rb
67
+ - lib/ork/model/finders.rb
68
+ - lib/ork/model.rb
69
+ - lib/ork/utils.rb
70
+ - lib/ork/version.rb
71
+ - lib/ork.rb
72
+ - ork.gemspec
73
+ - test/finders.rb
74
+ - test/helper.rb
75
+ - test/model.rb
76
+ - test/reference.rb
77
+ - test/test_riak_server.toml
78
+ - test/test_riak_server.toml.example
79
+ homepage: http://github.com/eMancu/ork
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.0.3
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Ruby modeling layer for Riak.
103
+ test_files:
104
+ - test/finders.rb
105
+ - test/helper.rb
106
+ - test/model.rb
107
+ - test/reference.rb
108
+ - test/test_riak_server.toml
109
+ - test/test_riak_server.toml.example