ashikawa-ar 0.1.2

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.
@@ -0,0 +1,6 @@
1
+ module Ashikawa
2
+ module AR
3
+ class InvalidRecord < RuntimeError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module Ashikawa
2
+ module AR
3
+ class UnsavedRecord < RuntimeError
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,24 @@
1
+ require "virtus"
2
+ require "aequitas"
3
+ require "active_support/concern"
4
+ require "ashikawa-ar/base"
5
+ require "ashikawa-ar/search"
6
+ require "ashikawa-ar/persistence"
7
+
8
+ module Ashikawa
9
+ module AR
10
+ module Model
11
+ extend ActiveSupport::Concern
12
+ include Base
13
+ include Search
14
+ include Persistence
15
+
16
+ included do
17
+ class_eval do
18
+ include Virtus
19
+ include Aequitas
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,200 @@
1
+ require "ashikawa-core"
2
+ require "ashikawa-ar/base"
3
+ require "active_support/concern"
4
+ require "ashikawa-ar/exceptions/invalid_record"
5
+ require "ashikawa-ar/exceptions/unsaved_record"
6
+
7
+ module Ashikawa
8
+ module AR
9
+ # Provides Persistence functionality for your model
10
+ module Persistence
11
+ extend ActiveSupport::Concern
12
+ # Save the document to the database returning false if invalid
13
+ #
14
+ # @return [self, false] Returns false if not saved
15
+ # @api public
16
+ # @example Save the document to the database
17
+ # sam = Person.new name: "Sam Lowry"
18
+ # sam.save
19
+ def save;end
20
+
21
+ # Save the document to the database throwing an exception if invalid
22
+ #
23
+ # @return [self]
24
+ # @raise [InvalidRecord] if the data is invalid
25
+ # @api public
26
+ # @example Save the document to the database
27
+ # sam = Person.new name: "Sam Lowry"
28
+ # sam.save!
29
+ def save!;end
30
+
31
+ # Save the document to the database even if it is invalid
32
+ #
33
+ # @return [self] Returns false if not saved
34
+ # @api public
35
+ # @example Save the document to the database
36
+ # sam = Person.new name: "Sam Lowry"
37
+ # sam.save_without_validation
38
+ def save_without_validation;end
39
+
40
+ # Reload the record from the database
41
+ #
42
+ # @return [self]
43
+ # @raise [UnsavedRecord] if the data is not yet saved
44
+ # @api public
45
+ # @example Get the updated version from the database
46
+ # sam.reload
47
+ def reload;end
48
+
49
+ # Delete the record from the database
50
+ #
51
+ # @return [self]
52
+ # @raise [UnsavedRecord] if the data is not yet saved
53
+ # @api public
54
+ # @example Get the updated version from the database
55
+ # sam.delete
56
+ def delete;end
57
+
58
+ # Update a single attribute and write to the database
59
+ #
60
+ # @param [String] key Name of the attribute
61
+ # @param [Object] value Value of the attribute
62
+ # @return [self]
63
+ # @raise [UnsavedRecord] if the data is not yet saved
64
+ # @api public
65
+ # @example Update the age
66
+ # sam.update_attribute "age", 39
67
+ def update_attribute(key, value);end
68
+
69
+ # Updates multiple attributes and write to the database
70
+ # returning false if they are invalid
71
+ #
72
+ # @param [Hash] attributes
73
+ # @return [self, false]
74
+ # @raise [UnsavedRecord] if the data is not yet saved
75
+ # @api public
76
+ # @example Update the age and favorite color
77
+ # sam.update_attributes age: 39, favorite_color: "Green"
78
+ def update_attributes(attributes);end
79
+
80
+ # Updates multiple attributes and write to the database
81
+ # throwing an exception if they are invalid
82
+ #
83
+ # @param [Hash] attributes
84
+ # @return [self]
85
+ # @raise [InvalidRecord] if the data is invalid
86
+ # @raise [UnsavedRecord] if the data is not yet saved
87
+ # @api public
88
+ # @example Update the age and favorite color
89
+ # sam.update_attributes! age: 39, favorite_color: "Green"
90
+ def update_attributes!(attributes);end
91
+
92
+ # Check, if the object has been persisted
93
+ #
94
+ # @return [Boolean]
95
+ # @api public
96
+ # @example Check, if sam is persisted
97
+ # sam.persisted?
98
+ def persisted?;end
99
+
100
+ # Check, if the object has been deleted
101
+ #
102
+ # @return [Boolean]
103
+ # @api public
104
+ # @example Check, if sam is deleted
105
+ # sam.deleted?
106
+ def deleted?;end
107
+
108
+ # Check, if the object is a new record
109
+ #
110
+ # @return [Boolean]
111
+ # @api public
112
+ # @example Check, if sam is a new record
113
+ # sam.new_record?
114
+ def new_record?;end
115
+
116
+ included do
117
+ class_eval do
118
+ def save
119
+ return false unless self.valid?
120
+ save_without_validation
121
+ end
122
+
123
+ def save!
124
+ raise InvalidRecord unless self.valid?
125
+ save_without_validation
126
+ end
127
+
128
+ def save_without_validation
129
+ if @id.nil?
130
+ response = self.class.collection.create self.attributes
131
+ @id = response.id
132
+ else
133
+ self.class.collection[@id] = self.attributes
134
+ end
135
+
136
+ @status = :persisted
137
+
138
+ self
139
+ end
140
+
141
+ def check_if_saved!
142
+ raise UnsavedRecord if @id.nil?
143
+ end
144
+
145
+ def reload
146
+ check_if_saved!
147
+ self.attributes = self.class.collection[@id]
148
+ self
149
+ end
150
+
151
+ def delete
152
+ check_if_saved!
153
+ self.class.collection[@id].delete
154
+ @id = nil
155
+ @status = :deleted
156
+ self
157
+ end
158
+
159
+ alias :destroy :delete
160
+
161
+ def update_attribute(key, value)
162
+ check_if_saved!
163
+ self[key] = value
164
+ self.save
165
+ end
166
+
167
+ def update_attributes(attributes)
168
+ check_if_saved!
169
+ attributes.each_pair do |key, value|
170
+ self[key] = value
171
+ end
172
+
173
+ self.save
174
+ end
175
+
176
+ def update_attributes!(attributes)
177
+ check_if_saved!
178
+ attributes.each_pair do |key, value|
179
+ self[key] = value
180
+ end
181
+
182
+ self.save!
183
+ end
184
+
185
+ def persisted?
186
+ @status == :persisted
187
+ end
188
+
189
+ def deleted?
190
+ @status == :deleted
191
+ end
192
+
193
+ def new_record?
194
+ @status.nil?
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,89 @@
1
+ require "ashikawa-core"
2
+ require "ashikawa-ar/base"
3
+ require "active_support/concern"
4
+
5
+ module Ashikawa
6
+ module AR
7
+ # Provides Search functionality for your model
8
+ module Search
9
+ extend ActiveSupport::Concern
10
+ # Find a document of the collection by ID
11
+ #
12
+ # @param [Fixnum] id ID of the document
13
+ # @return [Instance of Class]
14
+ # @api public
15
+ # @example Find a document by its ID
16
+ # person = Person.find my_id
17
+ # person.name #=> Johnny
18
+ def self.find(id);end
19
+
20
+ # Find a document using an AQL query
21
+ #
22
+ # @param [String] query The Query
23
+ # @return [Array<Instance of Class>]
24
+ # @api public
25
+ # @example Find documents with an AQL query
26
+ # people = Person.find_by_aql "FOR u IN people RETURN u"
27
+ # people.first.name #=> Johnny
28
+ def self.find_by_aql(query);end
29
+
30
+ # Find all documents with the provided attributes
31
+ #
32
+ # @param [Hash] example The attributes
33
+ # @return [Array<Instance of Class>]
34
+ # @api public
35
+ # @example Find a document by example
36
+ # people = Person.by_example name: "Johnny"
37
+ # people.first.name #=> Johnny
38
+ def self.by_example(example);end
39
+
40
+ # Find the first document with the provided attributes
41
+ #
42
+ # @param [Hash] example The attributes
43
+ # @return [Instance of Class]
44
+ # @api public
45
+ # @example Find a document by example
46
+ # people = Person.first_example name: "Johnny"
47
+ # people.name #=> Johnny
48
+ def self.first_example(example);end
49
+
50
+ # Find all documents
51
+ #
52
+ # @return [Array<Instance of Class>]
53
+ # @api public
54
+ # @example Find all documents
55
+ # people = Person.people
56
+ # people.first.name #=> Johnny
57
+ def self.all;end
58
+
59
+ included do
60
+ class_eval do
61
+ def self.find(id)
62
+ result = collection[id]
63
+ from_raw_document result
64
+ end
65
+
66
+ def self.find_by_aql(query)
67
+ results = database.query query
68
+ from_raw_documents results
69
+ end
70
+
71
+ def self.by_example(example)
72
+ results = collection.by_example example: example
73
+ from_raw_documents results
74
+ end
75
+
76
+ def self.first_example(example)
77
+ result = collection.first_example example
78
+ self.new result.to_hash["document"]
79
+ end
80
+
81
+ def self.all
82
+ results = collection.all
83
+ from_raw_documents results
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,18 @@
1
+ require "ashikawa-core"
2
+
3
+ module Ashikawa
4
+ module AR
5
+ def self.raw_setup(name, database)
6
+ Setup.databases[name] = database
7
+ end
8
+
9
+ def self.setup(name, location)
10
+ Setup.databases[name] = Ashikawa::Core::Database.new location
11
+ end
12
+
13
+ class Setup
14
+ class << self; attr_accessor :databases end
15
+ @databases = {}
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ module Ashikawa
2
+ module AR
3
+ VERSION = "0.1.2"
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ module Ashikawa
2
+ module Generators
3
+ # Generates a Model using Ashikawa::AR for Rails
4
+ class ModelGenerator < Rails::Generators::NamedBase
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ desc "Creates an Ashikawa::AR model"
8
+ argument :attributes,
9
+ type: :array,
10
+ default: [],
11
+ banner: "attribute[:type] attribute[:type]"
12
+
13
+ check_class_collision
14
+
15
+ def create_model_file
16
+ template "model.rb.tt",
17
+ File.join("app/models", class_path, "#{file_name}.rb")
18
+ end
19
+
20
+ hook_for :test_framework
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,7 @@
1
+ class <%= class_name %>
2
+ include Ashikawa::AR::Model
3
+
4
+ <% attributes.each do |attribute| -%>
5
+ attribute :<%= attribute.name %><% unless attribute.type.to_s == "string" %>, <%=attribute.type%><%end%>
6
+ <% end -%>
7
+ end
@@ -0,0 +1,10 @@
1
+ class Person
2
+ include Ashikawa::AR::Model
3
+
4
+ attribute :name
5
+ attribute :age, Integer
6
+ attribute :favorite_color
7
+
8
+ validates_presence_of :name, :age
9
+ validates_numericalness_of :age
10
+ end
@@ -0,0 +1,27 @@
1
+ RSpec.configure do |config|
2
+ raise "Could not find arangod. Please install it or check if it is in your path." if `which arangod` == ""
3
+
4
+ database_directory = "/tmp/ashikawa-integration"
5
+ arango_process = false
6
+
7
+ config.before(:suite) do
8
+ puts "Starting ArangoDB"
9
+ process_id = $$
10
+
11
+ Dir.mkdir database_directory unless Dir.exists? database_directory
12
+ arango_process = IO.popen("arangod #{database_directory} --watch-process #{process_id}")
13
+
14
+ sleep 2 # Wait for Arango to start up
15
+ end
16
+
17
+ config.after(:suite) do
18
+ puts
19
+ puts "Shutting down ArangoDB"
20
+
21
+ Process.kill "INT", arango_process.pid
22
+ sleep 2 # Wait for Arango to shut down
23
+ arango_process.close
24
+
25
+ `rm -r #{database_directory}/*`
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ require 'integration/spec_helper'
2
+ require 'examples/person.rb'
3
+
4
+ describe "Basics" do
5
+ it "should recognize the truth" do
6
+ true.should be_true
7
+ end
8
+
9
+ describe "basic functionality" do
10
+ subject { Person }
11
+
12
+ it "should provide virtus and aequitas" do
13
+ person = subject.new name: "George", age: "33"
14
+ person.age.should == 33
15
+ person.valid?.should be_true
16
+ end
17
+
18
+ it "should provide the collection name" do
19
+ subject.model_name.collection.should == "people"
20
+ end
21
+ end
22
+ end