hypostasis-repository 0.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 41927b984be679c93c5d3fd125c05aa56ba2fa7a
4
+ data.tar.gz: a54fe008d3bf333acd1759fd6db8a4a58177d166
5
+ SHA512:
6
+ metadata.gz: 5c45b815f9f85f6e503e1680d2c7dedbcd03a4a6e22562aaf5c21629a109e4ac3c447eea313a79a7a683ee3922ec8bdf3b53078cfbba7a4d8b61a7a1a0e74208
7
+ data.tar.gz: cb24913d08fcbad16598067b0a94465f98218313ed7f882b25f813784d550cc4407a12db6386faa99cdd23eb4a45153308faa9c3bdf494039bb36366353ff2d6
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,19 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - 2.1.1
7
+ branches:
8
+ only:
9
+ - master
10
+ - /^feature\/.*/
11
+ - /-stable$/
12
+ before_install:
13
+ - wget https://foundationdb.com/downloads/I_accept_the_FoundationDB_Community_License_Agreement/2.0.5/foundationdb-clients_2.0.5-1_amd64.deb
14
+ - wget https://foundationdb.com/downloads/I_accept_the_FoundationDB_Community_License_Agreement/2.0.5/foundationdb-server_2.0.5-1_amd64.deb
15
+ - sudo dpkg -i foundationdb-clients_2.0.5-1_amd64.deb
16
+ - sudo dpkg -i foundationdb-server_2.0.5-1_amd64.deb
17
+ addons:
18
+ code_climate:
19
+ repo_token: 5d610888b8cd96749841452722fbdb2e50f2f3a469ca0febff9e8bd2a5dd22bc
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hypostasis-repository.gemspec
4
+ gemspec
5
+
6
+ gem 'codeclimate-test-reporter', group: :test, require: nil
7
+ gem 'simplecov', '~> 0.7.1', group: :test, require: nil
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 jamesthompson
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,37 @@
1
+ # Hypostasis::Repository
2
+
3
+ [![Build Status](https://travis-ci.org/hypostasis/repository.svg)](https://travis-ci.org/hypostasis/repository)
4
+ [![Code Climate](https://codeclimate.com/github/hypostasis/repository.png)](https://codeclimate.com/github/hypostasis/repository)
5
+ [![Code Coverage](https://codeclimate.com/github/hypostasis/repository/coverage.png)](https://codeclimate.com/github/hypostasis/repository/code)
6
+
7
+ The Hypostasis::Repository project is intended to implement the Repository
8
+ pattern from Martin Fowler's "Patterns of Enterprise Application Architecture"
9
+ on top of FoundationDB. It includes two different storage strategies for the
10
+ domain models it stores: sparse and messagepack. It also includes support for
11
+ indexing and provides a means to customize mapping.
12
+
13
+ ## Installation
14
+
15
+ Add this line to your application's Gemfile:
16
+
17
+ gem 'hypostasis-repository'
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install hypostasis-repository
26
+
27
+ ## Usage
28
+
29
+ TODO: Write usage instructions here
30
+
31
+ ## Contributing
32
+
33
+ 1. Fork it ( http://github.com/<my-github-username>/hypostasis-repository/fork )
34
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
36
+ 4. Push to the branch (`git push origin my-new-feature`)
37
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ if system('vagrant --version > /dev/null 2>&1') && system('vagrant exec -h > /dev/null 2>&1')
7
+ desc 'Run specs within Vagrant'
8
+ task :vagrant_spec do
9
+ system 'vagrant exec rake spec'
10
+ end
11
+
12
+ task :default => :vagrant_spec
13
+ else
14
+ task :default => :spec
15
+ end
data/Vagrantfile ADDED
@@ -0,0 +1,22 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure('2') do |config|
5
+ config.vm.box = 'precise64'
6
+
7
+ config.vm.provider :virtualbox do |vb, override|
8
+ override.vm.box_url = 'http://files.vagrantup.com/precise64.box'
9
+ #vb.memory = 4096
10
+ end
11
+
12
+ config.vm.provider :vmware_fusion do |vw, override|
13
+ override.vm.box = 'precise64_vmware'
14
+ override.vm.box_url = 'http://files.vagrantup.com/precise64_vmware.box'
15
+ #vw.memory = 4096
16
+ end
17
+
18
+ config.vm.provision 'shell', path: 'provision.sh'
19
+
20
+ config.exec.root = '/vagrant'
21
+ config.exec.prepend_with 'bundle exec'
22
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hypostasis/repository/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hypostasis-repository"
8
+ spec.version = Hypostasis::Repository::VERSION
9
+ spec.authors = ["James Thompson"]
10
+ spec.email = ["james@plainprograms.com"]
11
+ spec.summary = %q{Implements the Repository pattern on top of FoundationDB}
12
+ spec.description = %q{Implements the Repository pattern on top of FoundationDB}
13
+ spec.homepage = "https://github.com/hypostasis/repository"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+
25
+ spec.add_dependency "fdb", "~> 2.0.0"
26
+ spec.add_dependency "activesupport", "~> 4.0"
27
+ end
@@ -0,0 +1,87 @@
1
+ require "active_support/concern"
2
+ require "fdb"
3
+ require "securerandom"
4
+
5
+ require "hypostasis/repository/version"
6
+
7
+ module Hypostasis
8
+ module Repository
9
+ extend ActiveSupport::Concern
10
+
11
+ included do
12
+ # ...
13
+ end
14
+
15
+ def initialize
16
+ setup_hypostasis_configuration
17
+ open_hypostasis_directory
18
+ super
19
+ end
20
+
21
+ def store(object)
22
+ repo_id = generate_repository_id
23
+ object_space = @hypostasis_directory[object.class.to_s][repo_id]
24
+ object.instance_variable_set(:@hypostasis_repository_id, repo_id)
25
+ @hypostasis[:database].transact do |tr|
26
+ tr.clear_range_start_with(object_space)
27
+ object.instance_variables.each do |ivar|
28
+ next if ivar == :@hypostasis_repository_id
29
+ tr.set(object_space[ivar.to_s], object.instance_variable_get(ivar))
30
+ end
31
+ end
32
+ object
33
+ end
34
+
35
+ def find(klass, criteria)
36
+ if criteria.is_a?(String)
37
+ find_by_id(klass, criteria)
38
+ elsif criteria.is_a?(Hash)
39
+ # ...
40
+ else
41
+ raise ArgumentError, 'criteria must be a String or Hash'
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def setup_hypostasis_configuration
48
+ ::FDB.api_version 200
49
+ instance_variable_set(:@hypostasis, {
50
+ database: ::FDB.open,
51
+ namespace: self.class.class_variable_get(:@@namespace)
52
+ })
53
+ end
54
+
55
+ def open_hypostasis_directory
56
+ directory = ::FDB.directory.create_or_open(@hypostasis[:database], @hypostasis[:namespace])
57
+ instance_variable_set(:@hypostasis_directory, directory)
58
+ end
59
+
60
+ def generate_repository_id
61
+ SecureRandom.hex(16)
62
+ end
63
+
64
+ def find_by_id(klass, id)
65
+ object_id = id.encode(Encoding::US_ASCII)
66
+ object_space = @hypostasis_directory[klass.to_s][object_id]
67
+ results = @hypostasis[:database].get_range_start_with(object_space)
68
+ return nil if results.empty? || results.nil?
69
+
70
+ object = klass.new
71
+ object.instance_variable_set(:@hypostasis_repository_id, object_id)
72
+ results.each do |key|
73
+ ivar = object_space.unpack(key.key)[0].to_sym
74
+ object.instance_variable_set(ivar, key.value)
75
+ end
76
+
77
+ object
78
+ end
79
+
80
+ module ClassMethods
81
+ def use_namespace(namespace)
82
+ namespace = namespace.is_a?(Array) ? namespace : namespace.split('/')
83
+ class_variable_set(:@@namespace, namespace)
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,5 @@
1
+ module Hypostasis
2
+ module Repository
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
data/provision.sh ADDED
@@ -0,0 +1,15 @@
1
+ #!/bin/bash
2
+ apt-get update && apt-get upgrade
3
+ apt-get -y install curl git
4
+
5
+ wget https://foundationdb.com/downloads/I_accept_the_FoundationDB_Community_License_Agreement/2.0.5/foundationdb-clients_2.0.5-1_amd64.deb
6
+ wget https://foundationdb.com/downloads/I_accept_the_FoundationDB_Community_License_Agreement/2.0.5/foundationdb-server_2.0.5-1_amd64.deb
7
+
8
+ sudo dpkg -i foundationdb-clients_2.0.5-1_amd64.deb foundationdb-server_2.0.5-1_amd64.deb
9
+
10
+ sudo su - vagrant
11
+ cd /home/vagrant
12
+ \curl -sSL https://get.rvm.io | bash -s stable --ruby
13
+ source /usr/local/rvm/scripts/rvm
14
+
15
+ cd /vagrant; bundle install
@@ -0,0 +1,15 @@
1
+ class Simple
2
+ attr_accessor :name, :dob, :notes
3
+
4
+ def initialize(attributes = {})
5
+ @name = attributes[:name] unless attributes[:name].nil?
6
+ @dob = attributes[:dob] unless attributes[:dob].nil?
7
+ @notes = attributes[:notes] unless attributes[:notes].nil?
8
+ end
9
+ end
10
+
11
+ class SimpleRepository
12
+ include Hypostasis::Repository
13
+
14
+ use_namespace 'simple/repository'
15
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hypostasis::Repository do
4
+ it 'should have a version number' do
5
+ Hypostasis::Repository::VERSION.should_not be_nil
6
+ end
7
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ require 'examples/simple_repository'
3
+
4
+ describe SimpleRepository do
5
+ let(:database) { ::FDB.open }
6
+ let(:directory) { ::FDB.directory.open(database, %w{simple repository}) }
7
+
8
+ let(:subject) { SimpleRepository.new }
9
+ let(:object) { Simple.new(name: 'John', dob: '1982-05-19', notes: 'An example') }
10
+
11
+ before :each do
12
+ subject
13
+ end
14
+
15
+ after :each do
16
+ ::FDB.directory.remove_if_exists(database, %w{simple repository})
17
+ end
18
+
19
+ it 'opening directory should not raise exception' do
20
+ expect { directory }.not_to raise_exception
21
+ end
22
+
23
+ it 'directory should exist' do
24
+ ::FDB.directory.exists?(database, %w{simple repository}).should be_true
25
+ end
26
+
27
+ describe 'storage' do
28
+ let(:result) { subject.store(object) }
29
+
30
+ before :each do
31
+ result
32
+ @id = object.instance_variable_get(:@hypostasis_repository_id).encode(Encoding::US_ASCII)
33
+ end
34
+
35
+ it { database.get(directory[object.class.to_s][@id][:@name.to_s]).value.should eq 'John' }
36
+ it { database.get(directory[object.class.to_s][@id][:@dob.to_s]).value.should eq '1982-05-19' }
37
+ it { database.get(directory[object.class.to_s][@id][:@notes.to_s]).value.should eq 'An example' }
38
+ it { database.get(directory[object.class.to_s][@id][:@hypostasis_repository_id.to_s]).should be_nil }
39
+ it { result.should eq object }
40
+ end
41
+
42
+ describe 'find with id' do
43
+ let(:result) { subject.find(Simple, @id) }
44
+
45
+ before :each do
46
+ subject.store(object)
47
+ @id = object.instance_variable_get(:@hypostasis_repository_id).encode(Encoding::US_ASCII)
48
+ end
49
+
50
+ it { result.class.should eq Simple }
51
+ it { result.instance_variable_get(:@hypostasis_repository_id).should eq @id }
52
+ it { result.name.should eq 'John' }
53
+ it { result.dob.should eq '1982-05-19' }
54
+ it { result.notes.should eq 'An example' }
55
+ end
56
+ end
@@ -0,0 +1,12 @@
1
+ if ENV['CI']
2
+ require 'codeclimate-test-reporter'
3
+ CodeClimate::TestReporter.start
4
+ else
5
+ require 'simplecov'
6
+ SimpleCov.start do
7
+ add_filter '/spec/'
8
+ end
9
+ end
10
+
11
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
12
+ require 'hypostasis/repository'
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hypostasis-repository
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - James Thompson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
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: rspec
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
+ - !ruby/object:Gem::Dependency
56
+ name: fdb
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 2.0.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 2.0.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '4.0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '4.0'
83
+ description: Implements the Repository pattern on top of FoundationDB
84
+ email:
85
+ - james@plainprograms.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - Vagrantfile
98
+ - hypostasis-repository.gemspec
99
+ - lib/hypostasis/repository.rb
100
+ - lib/hypostasis/repository/version.rb
101
+ - provision.sh
102
+ - spec/examples/simple_repository.rb
103
+ - spec/hypostasis/repository_spec.rb
104
+ - spec/hypostasis/simple_repository_spec.rb
105
+ - spec/spec_helper.rb
106
+ homepage: https://github.com/hypostasis/repository
107
+ licenses:
108
+ - MIT
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.2.2
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Implements the Repository pattern on top of FoundationDB
130
+ test_files:
131
+ - spec/examples/simple_repository.rb
132
+ - spec/hypostasis/repository_spec.rb
133
+ - spec/hypostasis/simple_repository_spec.rb
134
+ - spec/spec_helper.rb