dart 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +2 -0
- data/dart.gemspec +28 -0
- data/lib/dart.rb +1 -0
- data/lib/dart/active_record_model_reflection.rb +7 -0
- data/lib/dart/core.rb +17 -0
- data/lib/dart/core/association.rb +29 -0
- data/lib/dart/core/direct_association.rb +36 -0
- data/lib/dart/core/foreign_key_info.rb +8 -0
- data/lib/dart/core/many_to_many_association.rb +55 -0
- data/lib/dart/core/many_to_one_association.rb +18 -0
- data/lib/dart/core/one_to_many_association.rb +13 -0
- data/lib/dart/core/one_to_one_association.rb +17 -0
- data/lib/dart/core/relation.rb +46 -0
- data/lib/dart/database.rb +8 -0
- data/lib/dart/database/many_to_many_association.rb +14 -0
- data/lib/dart/database/many_to_one_association.rb +14 -0
- data/lib/dart/database/one_to_many_association.rb +14 -0
- data/lib/dart/database/relation.rb +21 -0
- data/lib/dart/database/test_helpers.rb +23 -0
- data/lib/dart/naming_conventions.rb +18 -0
- data/lib/dart/naming_conventions/abstract_base.rb +71 -0
- data/lib/dart/naming_conventions/association_helpers.rb +16 -0
- data/lib/dart/naming_conventions/direct_association_helpers.rb +21 -0
- data/lib/dart/naming_conventions/foreign_key_finder.rb +26 -0
- data/lib/dart/naming_conventions/many_to_many_association_helpers.rb +52 -0
- data/lib/dart/naming_conventions/many_to_one_association_helpers.rb +20 -0
- data/lib/dart/naming_conventions/one_to_many_association_helpers.rb +26 -0
- data/lib/dart/naming_conventions/relation_helpers.rb +40 -0
- data/lib/dart/reflection/abstract_resolver.rb +7 -0
- data/lib/dart/reflection/active_record_model/resolver.rb +122 -0
- data/lib/dart/reflection/orm_model_resolver.rb +64 -0
- data/lib/dart/reflection/sequel/naming_conventions.rb +25 -0
- data/lib/dart/reflection/sequel/sequelizer.rb +14 -0
- data/lib/dart/reflection/sequel_model/resolver.rb +78 -0
- data/lib/dart/reflection/sequel_table/foreign_key_finder.rb +50 -0
- data/lib/dart/reflection/sequel_table/reflector.rb +151 -0
- data/lib/dart/reflection/sequel_table/resolver.rb +60 -0
- data/lib/dart/reflection/sequel_table/schema.rb +52 -0
- data/lib/dart/sequel_model_reflection.rb +10 -0
- data/lib/dart/sequel_table_reflection.rb +26 -0
- data/lib/dart/version.rb +3 -0
- data/test/dart/database/many_to_many_association_test.rb +80 -0
- data/test/dart/naming_conventions/abstract_base_test.rb +38 -0
- data/test/dart/reflection/orm_model_resolver_test.rb +66 -0
- data/test/test_helper.rb +6 -0
- metadata +182 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 34a16d3441cb65b527d15f07df704baa20a934ac
|
4
|
+
data.tar.gz: 9d3ecf9a3c691056893402b58d8bd6c7bb8413b8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d7d392408a9436d8ec671b16f9983ff1d474c031ebb58a43e68a6963e61b26cb1f4e0dcdf38d2d1bfe491309491ebabdea5eb42351fe8c64535e9ba82f4dd006
|
7
|
+
data.tar.gz: cd0601ae56191ca328a8d0879f316eb3a6a87c841c21f4d535244c02ad7917ee3d0c1ac1bb9f79acd37c759bb5dd361e0c2a2a9654186e779b871815afbe74b6
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Ed Posnak
|
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,31 @@
|
|
1
|
+
# Dart
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'dart'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install dart
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it ( https://github.com/[my-github-username]/dart/fork )
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/dart.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dart/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dart"
|
8
|
+
spec.version = Dart::VERSION
|
9
|
+
spec.authors = ["Ed Posnak"]
|
10
|
+
spec.email = ["ed.posnak@gmail.com"]
|
11
|
+
spec.summary = %q{database association resolver toolkit}
|
12
|
+
spec.description = %q{database association resolver toolkit for postgres, activemodel, sequel, etc.}
|
13
|
+
spec.homepage = ""
|
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_dependency 'abstract_method'
|
22
|
+
|
23
|
+
spec.add_development_dependency 'pg'
|
24
|
+
spec.add_development_dependency 'sequel'
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'minitest'
|
28
|
+
end
|
data/lib/dart.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'dart/core'
|
data/lib/dart/core.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'singleton'
|
3
|
+
require 'abstract_method'
|
4
|
+
|
5
|
+
require_relative 'version'
|
6
|
+
require_relative 'naming_conventions/abstract_base'
|
7
|
+
|
8
|
+
require_relative 'core/foreign_key_info'
|
9
|
+
|
10
|
+
require_relative 'core/association'
|
11
|
+
require_relative 'core/direct_association'
|
12
|
+
require_relative 'core/one_to_one_association'
|
13
|
+
require_relative 'core/many_to_one_association'
|
14
|
+
require_relative 'core/one_to_many_association'
|
15
|
+
require_relative 'core/many_to_many_association'
|
16
|
+
|
17
|
+
require_relative 'core/relation'
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Dart
|
2
|
+
class Association
|
3
|
+
|
4
|
+
ONE_TO_ONE_TYPE = :one_to_one
|
5
|
+
ONE_TO_MANY_TYPE = :one_to_many
|
6
|
+
MANY_TO_ONE_TYPE = :many_to_one
|
7
|
+
MANY_TO_MANY_TYPE = :many_to_many
|
8
|
+
|
9
|
+
# used by ORM implementations to store the associated ORM model class and association options
|
10
|
+
attr_accessor :model_class
|
11
|
+
attr_accessor :scope
|
12
|
+
|
13
|
+
abstract_method :type, :associated_table
|
14
|
+
|
15
|
+
attr_reader :name
|
16
|
+
|
17
|
+
# @param [String|Symbol] ass_name
|
18
|
+
def set_name!(ass_name)
|
19
|
+
@name = ass_name.to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
# can be overriddent by *_to_one association types
|
23
|
+
def to_one?
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Dart
|
2
|
+
class DirectAssociation < Association
|
3
|
+
ATTRIBUTES = [:child_table, :foreign_key, :parent_table, :primary_key]
|
4
|
+
attr_reader *ATTRIBUTES
|
5
|
+
|
6
|
+
# Constructs a DirectAssociation from the given attributes, which must correspond to ATTRIBUTES defined above
|
7
|
+
# given either as separate arguments, a Hash, or an object that responds to methods corresponding to ATTRIBUTES
|
8
|
+
def initialize(*args)
|
9
|
+
if args.length == 1
|
10
|
+
obj_or_hash = args.first
|
11
|
+
obj = obj_or_hash.is_a?(Hash) ? OpenStruct.new(obj_or_hash) : obj_or_hash
|
12
|
+
else
|
13
|
+
obj = OpenStruct.new
|
14
|
+
ATTRIBUTES.each_with_index {|a, i| obj.send("#{a}=", args[i])}
|
15
|
+
end
|
16
|
+
@child_table = obj.child_table.to_s.freeze or raise "No child table in #{obj_or_hash}"
|
17
|
+
@foreign_key = obj.foreign_key.to_s.freeze or raise "No foreign_key in #{obj_or_hash}"
|
18
|
+
@parent_table = obj.parent_table.to_s.freeze or raise "No parent_table in #{obj_or_hash}"
|
19
|
+
@primary_key = obj.primary_key.to_s.freeze or raise "No primary_key in #{obj_or_hash}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def eql?(other)
|
23
|
+
ATTRIBUTES.all? { |f| send(f) == other.send(f) }
|
24
|
+
end
|
25
|
+
alias == eql?
|
26
|
+
|
27
|
+
def hash
|
28
|
+
ATTRIBUTES.map { |a| send(a) }.hash
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
"#{self.class} #{ATTRIBUTES.map { |a| "#{a}: #{send(a)}" }.join(', ')}"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Dart
|
2
|
+
class ManyToManyAssociation < Association
|
3
|
+
|
4
|
+
attr_reader :left_ass, :right_ass
|
5
|
+
protected :left_ass, :right_ass
|
6
|
+
|
7
|
+
# for an m2m association on users we'd pass in:
|
8
|
+
# left_ass: badge_users.user_id -> users.id
|
9
|
+
# right_ass: badge_users.badge_id -> badges.id
|
10
|
+
# =>
|
11
|
+
# many_to_many :badges, join_table: :badge_users
|
12
|
+
|
13
|
+
def initialize(left_ass, right_ass)
|
14
|
+
@left_ass, @right_ass = left_ass, right_ass
|
15
|
+
end
|
16
|
+
|
17
|
+
def join_associations
|
18
|
+
[left_ass, right_ass]
|
19
|
+
end
|
20
|
+
|
21
|
+
def type
|
22
|
+
MANY_TO_MANY_TYPE
|
23
|
+
end
|
24
|
+
|
25
|
+
def associated_table
|
26
|
+
right_ass.parent_table
|
27
|
+
end
|
28
|
+
|
29
|
+
def join_table
|
30
|
+
right_ass.child_table
|
31
|
+
end
|
32
|
+
|
33
|
+
def left_foreign_key
|
34
|
+
left_ass.foreign_key
|
35
|
+
end
|
36
|
+
|
37
|
+
def right_foreign_key
|
38
|
+
right_ass.foreign_key
|
39
|
+
end
|
40
|
+
|
41
|
+
def eql?(other)
|
42
|
+
join_associations.eql? other.join_associations
|
43
|
+
end
|
44
|
+
alias == eql?
|
45
|
+
|
46
|
+
def hash
|
47
|
+
join_associations.hash
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
"#{self.class}\n left:#{left_ass}\n right:#{right_ass}"
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Dart
|
2
|
+
class Relation
|
3
|
+
attr_reader :table_name, :column_names
|
4
|
+
|
5
|
+
attr_reader :associations
|
6
|
+
private :associations
|
7
|
+
|
8
|
+
def initialize(table, columns)
|
9
|
+
@table_name = table.to_s.freeze
|
10
|
+
@column_names = columns.map(&:to_s).map(&:freeze)
|
11
|
+
@associations = []
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [Array<Association>] list of all associations on this relation
|
15
|
+
def all_associations
|
16
|
+
associations
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Array<Association>] list of all direct (many_to_one or one_to_many) associations on this relation
|
20
|
+
def direct_associations
|
21
|
+
# associations - join_associations
|
22
|
+
parent_associations + child_associations
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Array<Association>] list of all join (many_to_many) associations on this relation
|
26
|
+
def join_associations
|
27
|
+
associations.select { |a| a.is_a?(ManyToManyAssociation) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def parent_associations
|
31
|
+
associations.select { |a| a.is_a?(ManyToOneAssociation) }
|
32
|
+
end
|
33
|
+
|
34
|
+
def child_associations
|
35
|
+
associations.select { |a| a.is_a?(OneToManyAssociation) }
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_association(ass)
|
39
|
+
associations << ass
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_s
|
43
|
+
table_name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require_relative 'core'
|
2
|
+
require_relative 'naming_conventions'
|
3
|
+
|
4
|
+
require_relative 'database/relation'
|
5
|
+
require_relative 'database/many_to_many_association'
|
6
|
+
require_relative 'database/many_to_one_association'
|
7
|
+
require_relative 'database/one_to_many_association'
|
8
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Dart
|
2
|
+
module Database
|
3
|
+
# A Database::ManyToManyAssociation extends Dart::ManyToManyAssociation with naming conventions
|
4
|
+
class ManyToManyAssociation < Dart::ManyToManyAssociation
|
5
|
+
include NamingConventions::ManyToManyAssociationHelpers
|
6
|
+
|
7
|
+
def initialize(*)
|
8
|
+
super
|
9
|
+
set_conventional_name!
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Dart
|
2
|
+
module Database
|
3
|
+
# A Database::ManyToOneAssociation extends Dart::ManyToOneAssociation with naming conventions
|
4
|
+
class ManyToOneAssociation < Dart::ManyToOneAssociation
|
5
|
+
include NamingConventions::ManyToOneAssociationHelpers
|
6
|
+
|
7
|
+
def initialize(*)
|
8
|
+
super
|
9
|
+
set_conventional_name!
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Dart
|
2
|
+
module Database
|
3
|
+
# A Database::OneToManyAssociation extends Dart::OneToManyAssociation with naming conventions
|
4
|
+
class OneToManyAssociation < Dart::OneToManyAssociation
|
5
|
+
include NamingConventions::OneToManyAssociationHelpers
|
6
|
+
|
7
|
+
def initialize(*)
|
8
|
+
super
|
9
|
+
set_conventional_name!
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|