diametric 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .jbundler
6
+ .rspec
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ bin/
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
21
+ vendor/
22
+ doc
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in diametric.gemspec
4
+ gemspec
5
+
6
+ # Development-only dependencies
7
+ gem 'rake'
8
+ gem 'pry'
9
+ gem 'rspec'
10
+
11
+ platform :mri do
12
+ gem 'yard'
13
+ gem 'redcarpet'
14
+ end
data/Guardfile ADDED
@@ -0,0 +1,8 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec' do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
+ watch('spec/spec_helper.rb') { "spec" }
8
+ end
data/Jarfile ADDED
@@ -0,0 +1,6 @@
1
+ repository 'http://clojars.org/repo/'
2
+ repository 'https://repository.jboss.org/nexus/content/groups/public/'
3
+
4
+ group :default, :runtime do
5
+ jar "com.datomic:datomic-free:0.8.3563"
6
+ end
data/Jarfile.lock ADDED
@@ -0,0 +1,126 @@
1
+ ---
2
+ version: 0.7.2
3
+ groups:
4
+ default:
5
+ dependencies:
6
+ - com.amazonaws:aws-java-sdk:jar:1.3.0
7
+ - com.datomic:datomic-free:jar:0.8.3563
8
+ - com.google.code.findbugs:jsr305:jar:1.3.9
9
+ - com.google.guava:guava:jar:12.0.1
10
+ - com.h2database:h2:jar:1.3.165
11
+ - com.jamesmurty.utils:java-xmlbuilder:jar:0.4
12
+ - commons-codec:commons-codec:jar:1.3
13
+ - commons-httpclient:commons-httpclient:jar:3.1
14
+ - net.java.dev.jets3t:jets3t:jar:0.8.1
15
+ - org.apache.httpcomponents:httpclient:jar:4.2-alpha1
16
+ - org.apache.httpcomponents:httpcore:jar:4.2-alpha2
17
+ - org.apache.lucene:lucene-core:jar:3.3.0
18
+ - org.apache.tomcat:tomcat-jdbc:jar:7.0.27
19
+ - org.apache.tomcat:tomcat-juli:jar:7.0.27
20
+ - org.clojure:clojure:jar:1.4.0
21
+ - org.clojure:data.json:jar:0.1.2
22
+ - org.codehaus.jackson:jackson-core-asl:jar:1.8.0
23
+ - org.codehaus.janino:commons-compiler-jdk:jar:2.6.1
24
+ - org.codehaus.janino:commons-compiler:jar:2.6.1
25
+ - org.hornetq:hornetq-core:jar:2.2.2.Final
26
+ - org.jboss.netty:netty:jar:3.2.4.Final
27
+ - org.slf4j:jcl-over-slf4j:jar:1.6.4
28
+ - org.slf4j:jul-to-slf4j:jar:1.6.4
29
+ - org.slf4j:log4j-over-slf4j:jar:1.6.4
30
+ - org.slf4j:slf4j-api:jar:1.6.4
31
+ - org.slf4j:slf4j-nop:jar:1.6.4
32
+ - postgresql:postgresql:jar:9.1-901.jdbc4
33
+ - spy:spymemcached:jar:2.8.1
34
+ artifacts:
35
+ - jar:com.datomic:datomic-free:jar:0.8.3563:
36
+ transitive:
37
+ com.h2database:h2:jar:1.3.165: {}
38
+ org.apache.lucene:lucene-core:jar:3.3.0: {}
39
+ postgresql:postgresql:jar:9.1-901.jdbc4: {}
40
+ spy:spymemcached:jar:2.8.1: {}
41
+ org.clojure:clojure:jar:1.4.0: {}
42
+ org.slf4j:jul-to-slf4j:jar:1.6.4:
43
+ org.slf4j:slf4j-api:jar:1.6.4: {}
44
+ com.google.guava:guava:jar:12.0.1:
45
+ com.google.code.findbugs:jsr305:jar:1.3.9: {}
46
+ org.clojure:data.json:jar:0.1.2: {}
47
+ org.slf4j:slf4j-nop:jar:1.6.4: {}
48
+ org.jboss.netty:netty:jar:3.2.4.Final: {}
49
+ org.codehaus.janino:commons-compiler-jdk:jar:2.6.1:
50
+ org.codehaus.janino:commons-compiler:jar:2.6.1: {}
51
+ org.apache.tomcat:tomcat-jdbc:jar:7.0.27:
52
+ org.apache.tomcat:tomcat-juli:jar:7.0.27: {}
53
+ org.hornetq:hornetq-core:jar:2.2.2.Final: {}
54
+ org.slf4j:jcl-over-slf4j:jar:1.6.4: {}
55
+ org.codehaus.jackson:jackson-core-asl:jar:1.8.0: {}
56
+ net.java.dev.jets3t:jets3t:jar:0.8.1:
57
+ com.jamesmurty.utils:java-xmlbuilder:jar:0.4: {}
58
+ commons-httpclient:commons-httpclient:jar:3.1: {}
59
+ commons-codec:commons-codec:jar:1.3: {}
60
+ org.slf4j:log4j-over-slf4j:jar:1.6.4: {}
61
+ com.amazonaws:aws-java-sdk:jar:1.3.0: {}
62
+ org.apache.httpcomponents:httpclient:jar:4.2-alpha1:
63
+ org.apache.httpcomponents:httpcore:jar:4.2-alpha2: {}
64
+ runtime:
65
+ dependencies:
66
+ - com.amazonaws:aws-java-sdk:jar:1.3.0
67
+ - com.datomic:datomic-free:jar:0.8.3563
68
+ - com.google.code.findbugs:jsr305:jar:1.3.9
69
+ - com.google.guava:guava:jar:12.0.1
70
+ - com.h2database:h2:jar:1.3.165
71
+ - com.jamesmurty.utils:java-xmlbuilder:jar:0.4
72
+ - commons-codec:commons-codec:jar:1.3
73
+ - commons-httpclient:commons-httpclient:jar:3.1
74
+ - net.java.dev.jets3t:jets3t:jar:0.8.1
75
+ - org.apache.httpcomponents:httpclient:jar:4.2-alpha1
76
+ - org.apache.httpcomponents:httpcore:jar:4.2-alpha2
77
+ - org.apache.lucene:lucene-core:jar:3.3.0
78
+ - org.apache.tomcat:tomcat-jdbc:jar:7.0.27
79
+ - org.apache.tomcat:tomcat-juli:jar:7.0.27
80
+ - org.clojure:clojure:jar:1.4.0
81
+ - org.clojure:data.json:jar:0.1.2
82
+ - org.codehaus.jackson:jackson-core-asl:jar:1.8.0
83
+ - org.codehaus.janino:commons-compiler-jdk:jar:2.6.1
84
+ - org.codehaus.janino:commons-compiler:jar:2.6.1
85
+ - org.hornetq:hornetq-core:jar:2.2.2.Final
86
+ - org.jboss.netty:netty:jar:3.2.4.Final
87
+ - org.slf4j:jcl-over-slf4j:jar:1.6.4
88
+ - org.slf4j:jul-to-slf4j:jar:1.6.4
89
+ - org.slf4j:log4j-over-slf4j:jar:1.6.4
90
+ - org.slf4j:slf4j-api:jar:1.6.4
91
+ - org.slf4j:slf4j-nop:jar:1.6.4
92
+ - postgresql:postgresql:jar:9.1-901.jdbc4
93
+ - spy:spymemcached:jar:2.8.1
94
+ artifacts:
95
+ - jar:com.datomic:datomic-free:jar:0.8.3563:
96
+ transitive:
97
+ com.h2database:h2:jar:1.3.165: {}
98
+ org.apache.lucene:lucene-core:jar:3.3.0: {}
99
+ postgresql:postgresql:jar:9.1-901.jdbc4: {}
100
+ spy:spymemcached:jar:2.8.1: {}
101
+ org.clojure:clojure:jar:1.4.0: {}
102
+ org.slf4j:jul-to-slf4j:jar:1.6.4:
103
+ org.slf4j:slf4j-api:jar:1.6.4: {}
104
+ com.google.guava:guava:jar:12.0.1:
105
+ com.google.code.findbugs:jsr305:jar:1.3.9: {}
106
+ org.clojure:data.json:jar:0.1.2: {}
107
+ org.slf4j:slf4j-nop:jar:1.6.4: {}
108
+ org.jboss.netty:netty:jar:3.2.4.Final: {}
109
+ org.codehaus.janino:commons-compiler-jdk:jar:2.6.1:
110
+ org.codehaus.janino:commons-compiler:jar:2.6.1: {}
111
+ org.apache.tomcat:tomcat-jdbc:jar:7.0.27:
112
+ org.apache.tomcat:tomcat-juli:jar:7.0.27: {}
113
+ org.hornetq:hornetq-core:jar:2.2.2.Final: {}
114
+ org.slf4j:jcl-over-slf4j:jar:1.6.4: {}
115
+ org.codehaus.jackson:jackson-core-asl:jar:1.8.0: {}
116
+ net.java.dev.jets3t:jets3t:jar:0.8.1:
117
+ com.jamesmurty.utils:java-xmlbuilder:jar:0.4: {}
118
+ commons-httpclient:commons-httpclient:jar:3.1: {}
119
+ commons-codec:commons-codec:jar:1.3: {}
120
+ org.slf4j:log4j-over-slf4j:jar:1.6.4: {}
121
+ com.amazonaws:aws-java-sdk:jar:1.3.0: {}
122
+ org.apache.httpcomponents:httpclient:jar:4.2-alpha1:
123
+ org.apache.httpcomponents:httpcore:jar:4.2-alpha2: {}
124
+ remote_repositories:
125
+ - http://clojars.org/repo/
126
+ - https://repository.jboss.org/nexus/content/groups/public/
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Clinton N. Dreisbach
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,215 @@
1
+ # Diametric
2
+
3
+ Diametric is a library for building schemas, queries, and transactions
4
+ for [Datomic][] from Ruby objects. It is also used to map Ruby objects
5
+ as entities into a Datomic database.
6
+
7
+ ## Entity API
8
+
9
+ The `Entity` module is interesting, in that it is primarily made of
10
+ pure functions that take their receiver (an instance of the class they
11
+ are included in) and return data that you can use in Datomic. This
12
+ makes it not an ORM-like thing at all, but instead a Ruby-ish data
13
+ builder for Datomic. And yet, a `Diametric::Entity` is fully
14
+ `ActiveModel` compliant! You can use them anywhere you would use an
15
+ `ActiveRecord` model or another `ActiveModel`-compliant instance.
16
+
17
+ They do not include all `ActiveModel` modules by default, only the
18
+ ones needed to establish compliance. You may want to include others
19
+ yourself, such as `Validations` or `Callbacks`.
20
+
21
+ ```ruby
22
+ require 'diametric'
23
+
24
+ class Person
25
+ include Diametric::Entity
26
+
27
+ attribute :name, String, :index => true
28
+ attribute :email, String, :cardinality => :many
29
+ attribute :birthday, DateTime
30
+ attribute :iq, Integer
31
+ attribute :website, URI
32
+ end
33
+
34
+ Person.schema
35
+ # Datomic transaction:
36
+ # [{:db/id #db/id[:db.part/db]
37
+ # :db/ident :person/name
38
+ # :db/valueType :db.type/string
39
+ # :db/cardinality :db.cardinality/one
40
+ # :db/index true
41
+ # :db.install/_attribute :db.part/db}
42
+ # {:db/id #db/id[:db.part/db]
43
+ # :db/ident :person/email
44
+ # :db/valueType :db.type/string
45
+ # :db/cardinality :db.cardinality/many
46
+ # :db.install/_attribute :db.part/db}
47
+ # {:db/id #db/id[:db.part/db]
48
+ # :db/ident :person/birthday
49
+ # :db/valueType :db.type/instant
50
+ # :db/cardinality :db.cardinality/one
51
+ # :db.install/_attribute :db.part/db}
52
+ # {:db/id #db/id[:db.part/db]
53
+ # :db/ident :person/iq
54
+ # :db/valueType :db.type/long
55
+ # :db/cardinality :db.cardinality/one
56
+ # :db.install/_attribute :db.part/db}
57
+ # {:db/id #db/id[:db.part/db]
58
+ # :db/ident :person/website
59
+ # :db/valueType :db.type/uri
60
+ # :db/cardinality :db.cardinality/one
61
+ # :db.install/_attribute :db.part/db}]
62
+
63
+ Person.attributes
64
+ # [:dbid, :name, :email, :birthday, :iq, :website]
65
+
66
+ person = Person.new(Hash[*(Person.attributes.zip(results_from_query).flatten)])
67
+ # or
68
+ person = Person.from_query(results_from_query)
69
+
70
+ person.iq = 180
71
+ person.tx_data(:iq)
72
+ # Datomic transaction:
73
+ # [{:db/id person.dbid
74
+ # :person/iq 180}]
75
+
76
+ person = Person.new(:name => "Peanut")
77
+ person.tx_data
78
+ # Datomic transaction:
79
+ # [{:db/id #db/id[:db.part/user]
80
+ # :person/name "Peanut"}]
81
+ ```
82
+
83
+ ## Query API
84
+
85
+ The query API is used for generating Datomic queries, whether to send via an external client or via the persistence API. The two methods used to generate a query are `.where` and `.filter`, both of which are chainable.
86
+
87
+ To get query data and args for a query, call `.data` on a `Query`.
88
+
89
+ If you are using a persistence API, you can ask `Query` to get the results of a Datomic query. `Diametric::Query` is an `Enumerable`. To get the results of a query, use `Enumerable` methods such as `.each` or `.first`. `Query` also provides a `.all` method to run the query and get the results.
90
+
91
+ ```ruby
92
+ query = Datomic::Query.new(Person).where(:name => "Clinton Dreisbach")
93
+ query.data
94
+ # Datomic query:
95
+ # [:find ?e ?name ?email ?birthday ?iq ?website
96
+ # :from $ ?name
97
+ # :where [?e :person/name ?name]
98
+ # [?e :person/email ?email]
99
+ # [?e :person/birthday ?birthday]
100
+ # [?e :person/iq ?iq]
101
+ # [?e :person/website ?website]]
102
+ # Args:
103
+ # ["Clinton Dreisbach"]
104
+ #
105
+ # Returns as an array, [query, args].
106
+
107
+ query = Datomic::Query.new(Person).where(:name => "Clinton Dreisbach").filter(:>, :iq, 150)
108
+ query.data
109
+ # Datomic query:
110
+ # [:find ?e ?name ?email ?birthday ?iq ?website
111
+ # :from $ ?name
112
+ # :where [?e :person/name ?name]
113
+ # [?e :person/email ?email]
114
+ # [?e :person/birthday ?birthday]
115
+ # [?e :person/iq ?iq]
116
+ # [?e :person/website ?website]
117
+ # [> ?iq 150]
118
+ # Args:
119
+ # ["Clinton Dreisbach"]
120
+ #
121
+ # Returns as an array, [query, args].
122
+ ```
123
+
124
+ ## Persistence API
125
+
126
+ The persistence API comes in two flavors: REST- and peer-based. For the most part, they have the same API.
127
+
128
+ ### Peer
129
+
130
+ With `Diametric::Persistence::Peer`, you can create objects that know how to store themselves to Datomic through a Datomic peer.
131
+
132
+ To use `Diametric::Persistence::Peer`, you will need to use JRuby and require `diametric/persistence/peer`. When you install the `diametric` gem with JRuby, all `.jar` files needed to run Datomic will be downloaded.
133
+
134
+ ```ruby
135
+ require 'diametric'
136
+ require 'diametric/persistence/peer'
137
+
138
+ # database URI
139
+ # will create database if it does not already exist
140
+ Diametric::Persistence::Peer.connect('datomic:mem://animals')
141
+ ```
142
+
143
+ ### REST
144
+
145
+ With `Diametric::Persistence::REST`, you can create objects that know how to store themselves to Datomic through the Datomic REST API. This is your only option unless you are using JRuby.
146
+
147
+ ```ruby
148
+ require 'diametric'
149
+ require 'diametric/persistence/rest'
150
+
151
+ # database url, database alias, database name
152
+ # will create database if it does not already exist
153
+ Diametric::Persistence::REST.connect('http://localhost:9000', 'test', 'animals')
154
+ ```
155
+
156
+ ### Using persisted models
157
+
158
+ ```ruby
159
+ class Goat
160
+ include Diametric::Entity
161
+ include Diametric::Persistence::REST # if using REST API
162
+ include Diametric::Persistence::Peer # if using JRuby and not using REST
163
+
164
+ attribute :name, String, :index => true
165
+ attribute :age, Integer
166
+ end
167
+
168
+ goat = Goat.new(:name => 'Beans', :age => 2)
169
+ goat.dbid # => nil
170
+ goat.name # => "Beans"
171
+ goat.persisted? # => false
172
+ goat.new? # => true
173
+
174
+ goat.save
175
+ goat.dbid # => new id autogenerated
176
+ goat.name # => "Beans"
177
+ goat.persisted? # => true
178
+ goat.new? # => false
179
+
180
+ goats = Goat.where(:name => "Beans")
181
+ #=> [Goat(id: 1, age: 2, name: "Beans")]
182
+
183
+ goat = Goat.first(:name => "Beans")
184
+ #=> Goat(id: 1, age: 2, name: "Beans")
185
+
186
+ goats = Goat.filter(:<, :age, 3)
187
+ #=> [Goat(id: 1, age: 2, name: "Beans")]
188
+
189
+ goats = Goat.filter(:>, :age, 3)
190
+ #=> []
191
+ ```
192
+
193
+ ## Installation
194
+
195
+ Add this line to your application's Gemfile:
196
+
197
+ gem 'diametric'
198
+
199
+ And then execute:
200
+
201
+ $ bundle
202
+
203
+ Or install it yourself as:
204
+
205
+ $ gem install diametric
206
+
207
+ ## Contributing
208
+
209
+ 1. Fork it
210
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
211
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
212
+ 4. Push to the branch (`git push origin my-new-feature`)
213
+ 5. Create new Pull Request
214
+
215
+ [Datomic]: http://www.datomic.com
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ begin
2
+ require "bundler/gem_tasks"
3
+ rescue LoadError
4
+ end
5
+
6
+ task :default => :prepare
7
+
8
+ task :prepare do
9
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
10
+ require 'lock_jar'
11
+
12
+ # get jarfile relative the gem dir
13
+ lockfile = File.expand_path("../Jarfile.lock", __FILE__)
14
+
15
+ LockJar.install(lockfile)
16
+ end
17
+ end
data/TODO.org ADDED
@@ -0,0 +1,12 @@
1
+ * Entity API
2
+ ** Add default values to attributes
3
+ ** People probably want validations by default: include ActiveModel::Validations
4
+
5
+ * Persistence API
6
+ ** Handle Java exceptions in the Peer persistence library
7
+ ** Handle exceptions from the REST client in the REST persistence library
8
+ ** Refactor so that Diametric::Persistence is the primary module and the connection determines different behavior
9
+ *** Yoko requests: .connect should take an argument :rest or :peer, #peer? and #rest? methods should be on the connection object
10
+
11
+ * History API
12
+ ** Make it