diametric 0.0.4 → 0.1.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.
Files changed (67) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +21 -18
  3. data/Jarfile +15 -1
  4. data/README.md +22 -14
  5. data/Rakefile +17 -1
  6. data/bin/datomic-rest +33 -0
  7. data/bin/download-datomic +13 -0
  8. data/datomic_version.yml +4 -0
  9. data/diametric.gemspec +9 -6
  10. data/ext/diametric/DiametricCollection.java +147 -0
  11. data/ext/diametric/DiametricConnection.java +113 -0
  12. data/ext/diametric/DiametricDatabase.java +107 -0
  13. data/ext/diametric/DiametricEntity.java +90 -0
  14. data/ext/diametric/DiametricListenableFuture.java +47 -0
  15. data/ext/diametric/DiametricObject.java +66 -0
  16. data/ext/diametric/DiametricPeer.java +414 -0
  17. data/ext/diametric/DiametricService.java +102 -0
  18. data/ext/diametric/DiametricUUID.java +61 -0
  19. data/ext/diametric/DiametricUtils.java +183 -0
  20. data/lib/boolean_type.rb +3 -0
  21. data/lib/diametric.rb +24 -0
  22. data/lib/diametric/entity.rb +219 -14
  23. data/lib/diametric/generators/active_model.rb +2 -2
  24. data/lib/diametric/persistence.rb +0 -1
  25. data/lib/diametric/persistence/common.rb +28 -9
  26. data/lib/diametric/persistence/peer.rb +122 -87
  27. data/lib/diametric/persistence/rest.rb +4 -3
  28. data/lib/diametric/query.rb +94 -23
  29. data/lib/diametric/rest_service.rb +74 -0
  30. data/lib/diametric/service_base.rb +77 -0
  31. data/lib/diametric/transactor.rb +86 -0
  32. data/lib/diametric/version.rb +1 -1
  33. data/lib/diametric_service.jar +0 -0
  34. data/lib/value_enums.rb +8 -0
  35. data/spec/conf_helper.rb +55 -0
  36. data/spec/config/free-transactor-template.properties +73 -0
  37. data/spec/config/logback.xml +59 -0
  38. data/spec/data/seattle-data0.dtm +452 -0
  39. data/spec/data/seattle-data1.dtm +326 -0
  40. data/spec/developer_create_sample.rb +39 -0
  41. data/spec/developer_query_spec.rb +120 -0
  42. data/spec/diametric/config_spec.rb +1 -1
  43. data/spec/diametric/entity_spec.rb +263 -0
  44. data/spec/diametric/peer_api_spec.rb +147 -0
  45. data/spec/diametric/persistence/peer_many2many_spec.rb +76 -0
  46. data/spec/diametric/persistence/peer_spec.rb +13 -22
  47. data/spec/diametric/persistence/rest_spec.rb +12 -19
  48. data/spec/diametric/query_spec.rb +4 -5
  49. data/spec/diametric/rest_service_spec.rb +56 -0
  50. data/spec/diametric/transactor_spec.rb +68 -0
  51. data/spec/integration_spec.rb +5 -3
  52. data/spec/parent_child_sample.rb +42 -0
  53. data/spec/peer_integration_spec.rb +106 -22
  54. data/spec/peer_seattle_spec.rb +200 -0
  55. data/spec/rc2013_seattle_big.rb +82 -0
  56. data/spec/rc2013_seattle_small.rb +60 -0
  57. data/spec/rc2013_simple_sample.rb +72 -0
  58. data/spec/seattle_integration_spec.rb +106 -0
  59. data/spec/simple_validation_sample.rb +31 -0
  60. data/spec/spec_helper.rb +31 -45
  61. data/spec/support/entities.rb +157 -0
  62. data/spec/support/gen_entity_class.rb +2 -0
  63. data/spec/support/persistence_examples.rb +9 -5
  64. data/spec/test_version_file.yml +4 -0
  65. metadata +131 -75
  66. data/Jarfile.lock +0 -134
  67. data/lib/jrclj.rb +0 -63
@@ -0,0 +1,74 @@
1
+ require 'diametric/service_base'
2
+
3
+ module Diametric
4
+ class RestService
5
+ include ::Diametric::ServiceBase
6
+ class << self
7
+ def datomic_command(datomic_home)
8
+ classpath = datomic_classpath(datomic_home)
9
+ command = ["java -server -Xmx1g", "-cp", classpath, "clojure.main", "-i", "#{datomic_home}/bin/bridge.clj", "--main datomic.rest"].flatten.join(" ")
10
+ end
11
+ end
12
+
13
+ attr_accessor :datomic_version, :datomic_version_no, :datomic_home, :pid
14
+ attr_accessor :host, :port, :db_alias, :uri
15
+
16
+ def initialize(conf="datomic_version.yml", dest="vendor/datomic")
17
+ @conf = conf
18
+ @dest = dest
19
+ @datomic_version = RestService.datomic_version(conf)
20
+ @datomic_home = File.join(File.dirname(__FILE__), "../..", dest, @datomic_version)
21
+ @datomic_version_no = RestService.datomic_version_no(@datomic_version)
22
+ @pid = nil
23
+ end
24
+
25
+ def start(opts={})
26
+ return if @pid
27
+ RestService.download(@conf, @dest)
28
+ command = RestService.datomic_command(@datomic_home)
29
+
30
+ require 'socket'
31
+ @host = opts[:host] ? opts[:host] : Socket.gethostname
32
+ @port = opts[:port] ? opts[:port] : 9000
33
+ @db_alias = opts[:db_alias] ? opts[:db_alias] : "free"
34
+ @uri = opts[:uri] ? opts[:uri] : "datomic:mem://"
35
+
36
+ uri = URI("http://#{@host}:#{@port}/")
37
+
38
+ unless port_available?(uri)
39
+ puts "Somebody is using #{@port}. Choose other."
40
+ return
41
+ end
42
+
43
+ temp_pid = spawn("#{command} -p #{@port} #{@db_alias} #{@uri}")
44
+
45
+ @pid = temp_pid if ready?(uri)
46
+ end
47
+
48
+ def stop
49
+ Process.kill("HUP", @pid) if @pid
50
+ @pid = nil
51
+ end
52
+
53
+ def port_available?(uri)
54
+ response = Net::HTTP.get_response(uri)
55
+ false
56
+ rescue Errno::ECONNREFUSED
57
+ true
58
+ end
59
+
60
+ def ready?(uri)
61
+ while true
62
+ begin
63
+ response = Net::HTTP.get_response(uri)
64
+ return true
65
+ rescue
66
+ sleep 1
67
+ redo
68
+ end
69
+ end
70
+ true
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,77 @@
1
+ require 'net/http'
2
+ require 'pathname'
3
+ require 'yaml'
4
+
5
+ module Diametric
6
+ module ServiceBase
7
+ def self.included(base)
8
+ base.send(:extend, ClassMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+ def datomic_conf_file?(file="datomic_version.yml")
13
+ if Pathname.new(file).relative?
14
+ file = File.join(File.dirname(__FILE__), "../..", file)
15
+ end
16
+ return File.exists?(file)
17
+ end
18
+
19
+ def datomic_version(conf="datomic_version.yml")
20
+ if datomic_conf_file?(conf)
21
+ datomic_names = File.read(File.join(File.dirname(__FILE__), "../..", conf))
22
+ datomic_versions = YAML.load(datomic_names)
23
+ if ENV['DIAMETRIC_ENV'] && (ENV['DIAMETRIC_ENV'] == "pro")
24
+ datomic_versions["pro"]
25
+ else
26
+ datomic_versions["free"]
27
+ end
28
+ else
29
+ conf
30
+ end
31
+ end
32
+
33
+ def datomic_version_no(datomic_version_str)
34
+ /(\d|\.)+/.match(datomic_version_str)[0]
35
+ end
36
+
37
+ def downloaded?(conf="datomic_version.yml", dest="vendor/datomic")
38
+ datomic_home = datomic_version(conf)
39
+ if Pathname.new(dest).relative?
40
+ dest = File.join(File.dirname(__FILE__), "..", "..", dest)
41
+ end
42
+ File.exists?(File.join(dest, datomic_home))
43
+ end
44
+
45
+ def download(conf="datomic_version.yml", dest="vendor/datomic")
46
+ return true if downloaded?(conf, dest)
47
+ version = datomic_version(conf)
48
+ url = "http://downloads.datomic.com/#{datomic_version_no(version)}/#{version}.zip"
49
+ if Pathname.new(dest).relative?
50
+ dest = File.join(File.dirname(__FILE__), "../..", dest)
51
+ end
52
+ require 'open-uri'
53
+ require 'zip/zipfilesystem'
54
+ open(url) do |zip_file|
55
+ Zip::ZipFile.open(zip_file.path) do |zip_path|
56
+ zip_path.each do |zip_entry|
57
+ file_path = File.join(dest, zip_entry.to_s)
58
+ FileUtils.mkdir_p(File.dirname(file_path))
59
+ zip_path.extract(zip_entry, file_path) { true }
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ def datomic_classpath(datomic_home)
66
+ # Find jar archives
67
+ jars = Dir["#{datomic_home}/lib/*.jar"]
68
+ jars += Dir["#{datomic_home}/*transactor*.jar"]
69
+
70
+ # Setup CLASSPATH
71
+ classpath = jars.join(File::PATH_SEPARATOR)
72
+ files = ["samples/clj", "bin", "resources"]
73
+ classpath += File::PATH_SEPARATOR + files.collect {|f| datomic_home + "/" + f}.join(File::PATH_SEPARATOR)
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,86 @@
1
+ require 'diametric/service_base'
2
+ require 'pathname'
3
+ require 'securerandom'
4
+
5
+ module Diametric
6
+ class Transactor
7
+ include ::Diametric::ServiceBase
8
+ class << self
9
+ def datomic_command(datomic_home)
10
+ classpath = datomic_classpath(datomic_home)
11
+ java_opts = "-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly"
12
+ command = ["java -server -Xmx1g -Xms1g", java_opts, "-cp", classpath, "clojure.main", "--main datomic.launcher"].flatten.join(" ")
13
+ end
14
+ end
15
+
16
+ attr_accessor :datomic_version, :datomic_version_no, :datomic_home, :pid
17
+ attr_accessor :host, :port, :db_alias, :uri
18
+
19
+ def initialize(conf="datomic_version.yml", dest="vendor/datomic")
20
+ @conf = conf
21
+ @dest = dest
22
+ @datomic_version = Transactor.datomic_version(conf)
23
+ if Pathname.new(dest).relative?
24
+ @datomic_home = File.join(File.dirname(__FILE__), "../..", dest, @datomic_version)
25
+ else
26
+ @datomic_home = File.join(dest, @datomic_version)
27
+ end
28
+ @datomic_version_no = Transactor.datomic_version_no(@datomic_version)
29
+ @hostname = nil
30
+ @port = nil
31
+ @pid = nil
32
+ end
33
+
34
+ def start(props)
35
+ return if @pid
36
+ Transactor.download(@conf, @dest)
37
+ command = Transactor.datomic_command(@datomic_home)
38
+
39
+ unless File.exists?(props)
40
+ puts "Transactor property file #{props} doesn't exist."
41
+ return
42
+ end
43
+ properties(props)
44
+ tmp_pid = spawn("#{command} #{props}")
45
+ if ready?
46
+ @pid = tmp_pid
47
+ end
48
+ @pid
49
+ end
50
+
51
+ def stop
52
+ Process.kill("HUP", @pid) if @pid
53
+ @pid = nil
54
+ end
55
+
56
+ def properties(props)
57
+ File.readlines(props).each do |line|
58
+ m = /^(host=)(.+)/.match(line)
59
+ if m && m[2]
60
+ @hostname = m[2]
61
+ end
62
+ m = /^(port=)(\d+)/.match(line)
63
+ if m && m[2]
64
+ @port = m[2]
65
+ end
66
+ end
67
+ end
68
+
69
+ def ready?
70
+ tmp_database = "datomic:free://#{@hostname}:#{port}/tmp_database-#{SecureRandom.uuid}"
71
+ while true
72
+ begin
73
+ if Diametric::Persistence::Peer.create_database(tmp_database)
74
+ Diametric::Persistence::Peer.delete_database(tmp_database)
75
+ return true
76
+ end
77
+ rescue
78
+ sleep 1
79
+ redo
80
+ end
81
+ end
82
+ true
83
+ end
84
+ end
85
+
86
+ end
@@ -1,3 +1,3 @@
1
1
  module Diametric
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.1"
3
3
  end
Binary file
@@ -0,0 +1,8 @@
1
+ module Kernel
2
+ def enum(syms)
3
+ prefix = self.name.downcase.sub(/::/, ".")
4
+ syms.each do |s|
5
+ const_set(s.to_s.upcase, ":#{prefix}/#{s.to_s.downcase.sub(/_/, "-")}")
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,55 @@
1
+ require 'rspec'
2
+ #require 'pry'
3
+
4
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
5
+ require 'lock_jar'
6
+ jar_file = File.join(File.dirname(__FILE__), "..", "Jarfile")
7
+ lock_file = File.join(File.dirname(__FILE__), "..", "Jarfile.lock")
8
+ LockJar.lock(jar_file)
9
+ LockJar.install(lock_file)
10
+ LockJar.load(lock_file)
11
+ end
12
+ require 'diametric'
13
+ #Dir["./spec/support/**/*.rb"].each {|f| require f}
14
+
15
+ RSpec.configure do |c|
16
+ # c.fail_fast = true
17
+
18
+ c.filter_run_excluding :integration => true unless ENV['INTEGRATION']
19
+ c.filter_run_excluding :jruby => (not is_jruby?)
20
+ c.filter_run_excluding :service => true unless ENV['RESTSERVICE']
21
+
22
+ c.filter_run_including :focused => true
23
+ c.alias_example_to :fit, :focused => true
24
+
25
+ c.run_all_when_everything_filtered = true
26
+ c.treat_symbols_as_metadata_keys_with_true_values = true
27
+
28
+ c.before(:suite) do
29
+ #@rest = Diametric::RestService.new("spec/test_version_file.cnf", "tmp/datomic")
30
+ #@rest.start(:port => 46291, :db_alias => @storage, :uri => "datomic:mem://")
31
+ #PID = @rest.pid
32
+ end
33
+
34
+ c.after(:suite) do
35
+ Diametric::Persistence::Peer.shutdown(true) if is_jruby?
36
+ #Process.kill("HUP", PID)
37
+ end
38
+ end
39
+
40
+ shared_examples "ActiveModel" do |model|
41
+ require 'test/unit/assertions'
42
+ require 'active_model/lint'
43
+ include Test::Unit::Assertions
44
+ include ActiveModel::Lint::Tests
45
+
46
+ active_model_lints = ActiveModel::Lint::Tests.public_instance_methods.map(&:to_s).grep(/^test/)
47
+
48
+ let(:model) { subject }
49
+
50
+ active_model_lints.each do |test_name|
51
+ it "#{test_name.sub(/^test_/, '')}" do
52
+ send(test_name)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,73 @@
1
+ ################################################################
2
+ # Basic connection settings.
3
+
4
+ protocol=free
5
+ host=localhost
6
+ port=39082
7
+
8
+
9
+
10
+ ## OPTIONAL ####################################################
11
+ # The dev: and free: protocols typically use three ports
12
+ # starting with the selected :port, but you can specify the
13
+ # other ports explicitly, e.g. for virtualization environs
14
+ # that do not issue contiguous ports.
15
+
16
+ # h2-port=4335
17
+ # h2-web-port=4336
18
+
19
+
20
+
21
+ ################################################################
22
+ # See http://docs.datomic.com/capacity.html
23
+
24
+
25
+ # Recommended settings for -Xmx4g, ongoing usage.
26
+ memory-index-threshold=32m
27
+ memory-index-max=128m
28
+ object-cache-max=1g
29
+
30
+ # Recommended settings for -Xmx4g import jobs.
31
+ # memory-index-threshold=512m
32
+ # memory-index-max=1g
33
+ # object-cache-max=1g
34
+
35
+ # Recommended settings for -Xmx1g usage, e.g. dev laptops.
36
+ # memory-index-threshold=32m
37
+ # memory-index-max=128m
38
+ # object-cache-max=128m
39
+
40
+
41
+
42
+ ## OPTIONAL ####################################################
43
+
44
+
45
+ # Set to false to disable SSL between the peers and the transactor.
46
+ # Default: true
47
+ # encrypt-channel=true
48
+
49
+ # Data directory is used for dev: and free: storage, and
50
+ # as a temporary directory for all storages.
51
+ data-dir=tmp/data
52
+
53
+ # Transactor will log here, see bin/logback.xml to configure logging.
54
+ log-dir=tmp/log
55
+
56
+ # Transactor will write process pid here on startup
57
+ pid-file=tmp/transactor.pid
58
+
59
+
60
+
61
+ ## OPTIONAL ####################################################
62
+ # See http://docs.datomic.com/capacity.html
63
+
64
+
65
+ # Soft limit on the number of concurrent writes to storage.
66
+ # Default: 4, Miniumum: 2
67
+ # write-concurrency=4
68
+
69
+ # Soft limit on the number of concurrent reads to storage.
70
+ # Default: 2 times write-concurrency, Miniumum: 2
71
+ # read-concurrency=8
72
+
73
+
@@ -0,0 +1,59 @@
1
+ <configuration>
2
+
3
+ <!-- prevent per-message overhead for jul logging calls, e.g. Hornet -->
4
+ <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
5
+ <resetJUL>true</resetJUL>
6
+ </contextListener>
7
+
8
+ <appender name="MAIN" class="ch.qos.logback.core.rolling.RollingFileAppender">
9
+ <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
10
+ <fileNamePattern>${DATOMIC_LOG_DIR:-log}/%d{yyyy-MM-dd}.log</fileNamePattern>
11
+ <maxHistory>72</maxHistory>
12
+ </rollingPolicy>
13
+ <prudent>true</prudent> <!-- multi jvm safe, slower -->
14
+ <encoder>
15
+ <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %-10contextName %logger{36} - %msg%n</pattern>
16
+ </encoder>
17
+ </appender>
18
+
19
+ <!-- uncomment to log storage access -->
20
+ <!-- <logger name="datomic.kv-cluster" level="DEBUG"/> -->
21
+
22
+ <!-- uncomment to log transactor heartbeat -->
23
+ <!-- <logger name="datomic.lifecycle" level="DEBUG"/> -->
24
+
25
+ <!-- uncomment to log transactions (transactor side) -->
26
+ <!-- <logger name="datomic.transaction" level="DEBUG"/> -->
27
+
28
+ <!-- uncomment to log transactions (peer side) -->
29
+ <!-- <logger name="datomic.peer" level="DEBUG"/> -->
30
+
31
+ <!-- uncomment to log the transactor log -->
32
+ <!-- <logger name="datomic.log" level="DEBUG"/> -->
33
+
34
+ <!-- uncomment to log peer connection to transactor -->
35
+ <!-- <logger name="datomic.connector" level="DEBUG"/> -->
36
+
37
+ <!-- uncomment to log storage gc -->
38
+ <!-- <logger name="datomic.garbage" level="DEBUG"/> -->
39
+
40
+ <!-- these namespsaces create a ton of log noise -->
41
+ <logger name="httpclient" level="INFO"/>
42
+ <logger name="org.apache.commons.httpclient" level="INFO"/>
43
+ <logger name="org.apache.http" level="INFO"/>
44
+ <logger name="org.jets3t" level="INFO"/>
45
+ <logger name="com.amazonaws" level="INFO"/>
46
+ <logger name="com.amazonaws.request" level="WARN"/>
47
+ <logger name="sun.rmi" level="INFO"/>
48
+ <logger name="net.spy.memcached" level="INFO"/>
49
+ <logger name="com.couchbase.client" level="INFO"/>
50
+ <logger name="org.apache.zookeeper" level="INFO"/>
51
+ <logger name="com.ning.http.client.providers.netty" level="INFO"/>
52
+ <logger name="org.eclipse.jetty" level="INFO"/>
53
+ <logger name="org.hornetq.core.client.impl" level="INFO"/>
54
+ <logger name="org.apache.tomcat.jdbc.pool" level="INFO"/>
55
+
56
+ <root level="info">
57
+ <appender-ref ref="MAIN"/>
58
+ </root>
59
+ </configuration>