zeng 0.0.1 → 0.0.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.
Files changed (44) hide show
  1. data/README.md +67 -0
  2. data/Rakefile +21 -19
  3. data/book.rb +23 -0
  4. data/{init.rb → lib/zeng.rb} +5 -1
  5. data/lib/{cute_kv → zeng}/adapters/tokyo_cabinet.rb +7 -6
  6. data/lib/zeng/adapters/tokyo_tyrant.rb +30 -0
  7. data/lib/zeng/connector.rb +28 -0
  8. data/lib/{cute_kv → zeng}/document.rb +7 -12
  9. data/lib/{cute_kv → zeng}/indexer.rb +2 -2
  10. data/spec/case/document_test.rb +174 -174
  11. data/spec/case/indexer_test.rb +31 -31
  12. data/spec/helper.rb +12 -14
  13. data/spec/model/Account.rb +3 -3
  14. data/spec/model/Book.rb +2 -2
  15. data/spec/model/Friend.rb +3 -3
  16. data/spec/model/Icon.rb +3 -3
  17. data/spec/model/Project.rb +2 -2
  18. data/spec/model/User.rb +3 -4
  19. metadata +26 -49
  20. data/README.rdoc +0 -89
  21. data/lib/cute_kv/adapters/light_cloud.rb +0 -22
  22. data/lib/cute_kv/adapters/tokyo_tyrant.rb +0 -22
  23. data/lib/cute_kv/associations.rb +0 -285
  24. data/lib/cute_kv/connector.rb +0 -27
  25. data/lib/cute_kv/ext/string.rb +0 -34
  26. data/lib/cute_kv/ext/symbol.rb +0 -9
  27. data/lib/cute_kv/serialization.rb +0 -95
  28. data/lib/cute_kv/serializers/json_serializer.rb +0 -75
  29. data/lib/cute_kv/serializers/xml_serializer.rb +0 -325
  30. data/lib/cute_kv/timestamp.rb +0 -56
  31. data/lib/cute_kv/validations.rb +0 -68
  32. data/lib/cutekv.rb +0 -17
  33. data/spec/asso.yml +0 -23
  34. data/spec/asso_sin_plural.yml +0 -36
  35. data/spec/case/associations_test.rb +0 -313
  36. data/spec/case/document_docking_test.rb +0 -103
  37. data/spec/case/serialization_test.rb +0 -78
  38. data/spec/case/sin_plu_dic_test.rb +0 -29
  39. data/spec/case/symmetry_test.rb +0 -80
  40. data/spec/case/timestamp_test.rb +0 -65
  41. data/spec/case/validations_test.rb +0 -74
  42. data/spec/light_cloud.yml +0 -9
  43. data/spec/model/Topic.rb +0 -26
  44. data/tags +0 -322
@@ -3,38 +3,38 @@ ModelDivider.divide "User", "Icon", "Project"
3
3
 
4
4
  class IndexerTest < Test::Unit::TestCase
5
5
 
6
- def setup
7
- User.clear
8
- Project.clear
9
- @aaron = User.create(:name=>'aaron', :email=>'aaron@nonobo.com')
10
- @jim = User.create(:name=>'jim', :email=>'jim@nonobo.com')
11
- @jim_d = User.create(:name=>'jim', :email=>'aaron@nonobo.com')
12
- @jack = User.create(:name=>'jack', :email=>'jack@nonobo.com')
13
- @kame = User.create(:name=>'kame', :email=>'kame@nonobo.com')
14
- @nonobo = Project.create(:name=>"nonobo")
15
- end
6
+ def setup
7
+ User.clear
8
+ Project.clear
9
+ @aaron = User.create(:name=>'aaron', :email=>'aaron@nonobo.com')
10
+ @jim = User.create(:name=>'jim', :email=>'jim@nonobo.com')
11
+ @jim_d = User.create(:name=>'jim', :email=>'aaron@nonobo.com')
12
+ @jack = User.create(:name=>'jack', :email=>'jack@nonobo.com')
13
+ @kame = User.create(:name=>'kame', :email=>'kame@nonobo.com')
14
+ @nonobo = Project.create(:name=>"nonobo")
15
+ end
16
16
 
17
- def test_indexer_base
18
- assert CuteKV::Indexer::map(User=>['name', 'email'])
19
- assert CuteKV::Indexer::map(Project=>'created_at')
20
- assert User.indexes == []
21
- User.indexes << @aaron
22
- User.indexes << @jim
23
- User.indexes << @jim_d
24
- User.indexes << @jack
25
- User.indexes << @jim
26
- User.indexes << @aaron
27
- assert User.indexes.size==4
28
- assert User.indexes.include?([@aaron.id,{"id"=>@aaron.id, "name"=>@aaron.name, "email"=>@aaron.email}])
29
- assert User.indexes.include?([@jim.id,{"id"=>@jim.id, "name"=>@jim.name, "email"=>@jim.email}])
30
- assert User.indexes.include?([@jim_d.id,{"id"=>@jim_d.id, "name"=>@jim_d.name, "email"=>@jim_d.email}])
31
- assert User.indexes.include?([@jack.id,{"id"=>@jack.id, "name"=>@jack.name, "email"=>@jack.email}])
32
- assert User.respond_to?(:find_all_by_email)
33
- assert User.find_all_by_name("aaron")[0].name=="aaron"
34
- assert User.find_all_by_name("jim").size==2
35
- assert_equal User.find_all_by_email("aaron@nonobo.com").size,2
36
- assert_equal User.find_all_by_email("aaron@nonobo.com")[0].email, "aaron@nonobo.com"
37
- end
17
+ def test_indexer_base
18
+ assert Zeng::Indexer::map(User=>['name', 'email'])
19
+ assert Zeng::Indexer::map(Project=>'created_at')
20
+ assert User.indexes == []
21
+ User.indexes << @aaron
22
+ User.indexes << @jim
23
+ User.indexes << @jim_d
24
+ User.indexes << @jack
25
+ User.indexes << @jim
26
+ User.indexes << @aaron
27
+ assert User.indexes.size == 4
28
+ assert User.indexes.include?([@aaron.id,{"id"=>@aaron.id, "name"=>@aaron.name, "email"=>@aaron.email}])
29
+ assert User.indexes.include?([@jim.id,{"id"=>@jim.id, "name"=>@jim.name, "email"=>@jim.email}])
30
+ assert User.indexes.include?([@jim_d.id,{"id"=>@jim_d.id, "name"=>@jim_d.name, "email"=>@jim_d.email}])
31
+ assert User.indexes.include?([@jack.id,{"id"=>@jack.id, "name"=>@jack.name, "email"=>@jack.email}])
32
+ assert User.respond_to?(:find_all_by_email)
33
+ assert User.find_all_by_name("aaron")[0].name=="aaron"
34
+ assert User.find_all_by_name("jim").size==2
35
+ assert_equal User.find_all_by_email("aaron@nonobo.com").size,2
36
+ assert_equal User.find_all_by_email("aaron@nonobo.com")[0].email, "aaron@nonobo.com"
37
+ end
38
38
 
39
39
 
40
40
  end
@@ -1,27 +1,25 @@
1
1
  require 'pathname'
2
-
3
- require File.join(File.dirname(__FILE__), '..','lib','cutekv')
4
-
2
+ require File.join(File.dirname(__FILE__), '..','lib','zeng')
5
3
  require 'test/unit'
6
4
 
7
5
  def uses_mocha(description)
8
- require 'rubygems'
9
- require 'mocha'
10
- yield
6
+ require 'rubygems'
7
+ require 'mocha'
8
+ yield
11
9
  rescue LoadError
12
- $stderr.puts "Skipping #{description} tests. `gem install mocha` and try again."
10
+ $stderr.puts "Skipping #{description} tests. `gem install mocha` and try again."
13
11
  end
14
12
 
15
13
  module ModelDivider
16
14
 
17
- def self.divide(*models)
18
- models.size > 1 ? models.each {|model| divide(model)} : require(locate(models))
19
- end
15
+ def self.divide(*models)
16
+ models.size > 1 ? models.each {|model| divide(model)} : require(locate(models))
17
+ end
20
18
 
21
- protected
22
- def self.locate(model)
23
- File.join(File.dirname(__FILE__), "model", "#{model.to_s}")
24
- end
19
+ protected
20
+ def self.locate(model)
21
+ File.join(File.dirname(__FILE__), "model", "#{model.to_s}")
22
+ end
25
23
 
26
24
  end
27
25
 
@@ -1,5 +1,5 @@
1
- class Account
2
- include CuteKV::Document
3
- assign :name, :email
1
+ class Account
2
+ include Zeng::Document
3
+ assign :name, :email
4
4
  backend_configure(:TT, '127.0.0.1:1986')
5
5
  end
@@ -1,5 +1,5 @@
1
- class Book
2
- include CuteKV::Document
1
+ class Book
2
+ include Zeng::Document
3
3
  backend_configure(:TT, '127.0.0.1:1988')
4
4
  assign(:name)
5
5
  end
@@ -1,4 +1,4 @@
1
- class Friend
2
- include CuteKV::Document
3
- assign :name
1
+ class Friend
2
+ include Zeng::Document
3
+ assign :name
4
4
  end
@@ -1,5 +1,5 @@
1
- class Icon
2
- include CuteKV::Document
3
- assign :name, :path
1
+ class Icon
2
+ include Zeng::Document
3
+ assign :name, :path
4
4
  backend_configure(:TT, '127.0.0.1:1986')
5
5
  end
@@ -1,5 +1,5 @@
1
- class Project
2
- include CuteKV::Document
1
+ class Project
2
+ include Zeng::Document
3
3
  assign :name
4
4
  backend_configure(:TT, '127.0.0.1:1987')
5
5
  end
@@ -1,6 +1,5 @@
1
- class User
2
- include CuteKV::Document
3
- assign :name, :email
1
+ class User
2
+ include Zeng::Document
3
+ assign :name, :email
4
4
  backend_configure(:TT, '127.0.0.1:1985')
5
-
6
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zeng
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Guimin Jiang
@@ -15,11 +15,11 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-10 00:00:00 +08:00
18
+ date: 2011-01-04 00:00:00 +08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- name: ffi
22
+ name: json
23
23
  prerelease: false
24
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
25
  none: false
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: "0"
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
- description:
35
+ description: " Zeng(\xE7\xBD\xBE) is a fishing tool\xEF\xBC\x8C it is target to capture data in nosql database\xE3\x80\x82\n"
36
36
  email:
37
37
  - kayak.jiang@gmail.com
38
38
  executables: []
@@ -42,50 +42,29 @@ extensions: []
42
42
  extra_rdoc_files: []
43
43
 
44
44
  files:
45
- - ./lib/cute_kv/timestamp.rb
46
- - ./lib/cute_kv/serializers/json_serializer.rb
47
- - ./lib/cute_kv/serializers/xml_serializer.rb
48
- - ./lib/cute_kv/associations.rb
49
- - ./lib/cute_kv/indexer.rb
50
- - ./lib/cute_kv/connector.rb
51
- - ./lib/cute_kv/serialization.rb
52
- - ./lib/cute_kv/ext/string.rb
53
- - ./lib/cute_kv/ext/symbol.rb
54
- - ./lib/cute_kv/validations.rb
55
- - ./lib/cute_kv/document.rb
56
- - ./lib/cute_kv/adapters/tokyo_tyrant.rb
57
- - ./lib/cute_kv/adapters/tokyo_cabinet.rb
58
- - ./lib/cute_kv/adapters/light_cloud.rb
59
- - ./lib/cutekv.rb
60
- - ./tags
61
- - ./CHANGE
62
- - ./Rakefile
63
45
  - ./MIT-LICENSE
64
- - ./README.rdoc
65
- - ./init.rb
66
- - ./spec/model/Project.rb
46
+ - ./Rakefile
47
+ - ./TODOLIST
48
+ - ./CHANGE
49
+ - ./README.md
67
50
  - ./spec/model/Icon.rb
68
- - ./spec/model/Friend.rb
69
51
  - ./spec/model/User.rb
70
- - ./spec/model/Topic.rb
52
+ - ./spec/model/Friend.rb
53
+ - ./spec/model/Project.rb
71
54
  - ./spec/model/Book.rb
72
55
  - ./spec/model/Account.rb
73
- - ./spec/case/timestamp_test.rb
74
- - ./spec/case/validations_test.rb
75
- - ./spec/case/symmetry_test.rb
76
- - ./spec/case/sin_plu_dic_test.rb
77
- - ./spec/case/serialization_test.rb
78
- - ./spec/case/document_docking_test.rb
79
- - ./spec/case/associations_test.rb
80
- - ./spec/case/document_test.rb
81
- - ./spec/case/indexer_test.rb
82
56
  - ./spec/helper.rb
83
- - ./spec/asso.yml
84
- - ./spec/light_cloud.yml
85
- - ./spec/asso_sin_plural.yml
86
- - ./TODOLIST
57
+ - ./spec/case/indexer_test.rb
58
+ - ./spec/case/document_test.rb
59
+ - ./lib/zeng.rb
60
+ - ./lib/zeng/indexer.rb
61
+ - ./lib/zeng/adapters/tokyo_tyrant.rb
62
+ - ./lib/zeng/adapters/tokyo_cabinet.rb
63
+ - ./lib/zeng/connector.rb
64
+ - ./lib/zeng/document.rb
65
+ - ./book.rb
87
66
  has_rdoc: true
88
- homepage:
67
+ homepage: https://github.com/baya/zeng
89
68
  licenses: []
90
69
 
91
70
  post_install_message:
@@ -98,12 +77,10 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
77
  requirements:
99
78
  - - ">="
100
79
  - !ruby/object:Gem::Version
101
- hash: 59
80
+ hash: 3
102
81
  segments:
103
- - 1
104
- - 8
105
- - 6
106
- version: 1.8.6
82
+ - 0
83
+ version: "0"
107
84
  required_rubygems_version: !ruby/object:Gem::Requirement
108
85
  none: false
109
86
  requirements:
@@ -119,6 +96,6 @@ rubyforge_project:
119
96
  rubygems_version: 1.3.7
120
97
  signing_key:
121
98
  specification_version: 3
122
- summary: A chinese fishing tool
99
+ summary: Zeng -- a data mapper tool for nosql database
123
100
  test_files: []
124
101
 
@@ -1,89 +0,0 @@
1
- = CuteKV -- based at Ruby for object-key/value map
2
-
3
-
4
- == Main features
5
- * Independent Object Storage
6
-
7
- Through backend_configure to appoint storage location
8
- class User < ActiveObject::Base
9
- backend_configure :TT,"127.0.0.1:1987"
10
- end
11
-
12
- * Customize define persistent properties
13
- you can assign persitent properties by <t>assign</t> method,and set default value for
14
- each property.
15
-
16
- class User
17
- include CuteKV::Document
18
- backend_configure :TT,"127.0.0.1:1987"
19
- assign :name,:email, :gender=>'male', :age=>25
20
- end
21
-
22
- ==Object's associations
23
-
24
- Using CuteKV::associations module, we can description associations between objects
25
-
26
-
27
- class User
28
- include CuteKV::Document
29
- backend_configure :TT,"127.0.0.1:1987"
30
- assign :name,:email, :gender=>'male', :age=>25
31
- end
32
-
33
- CuteKV::associations::map(User=>:icon, Icon=>:user) #=>user has one icon and icon belongs to one user
34
- CuteKV::associations::map(User=>:friends) #=>user has many friends
35
-
36
- class Icon < ActiveObject::Base
37
- include CuteKV::Document
38
- backend_configure :TT,"127.0.0.1:1987"
39
- assign :content
40
- end
41
-
42
- ==Validations
43
- now CuteKV support validations by a simple method <t>validate</t> from CuteKV::Validations module
44
- I just keep it simple or i will improve it to approach activerecord's validations
45
- class User
46
- include CuteKV::Document
47
- incude CuteKV::Validations
48
- backend_configure :TT,"127.0.0.1:1987"
49
- assign :name,:email, :gender=>'male', :age=>25
50
- validate :name_presence_valid
51
-
52
- def name_presence_valid
53
- errors.add(:name, "name should not blank") if self.name.blank?
54
- end
55
- end
56
-
57
- @jim = User.create()
58
- @jim.save #=>nil
59
- User.find(@jim.id) #=>nil
60
- @jim.errors_message_on(:name) #=>"name should not blank"
61
-
62
-
63
- ==Index
64
- class User
65
- include CuteKV::Document
66
- backend_configure :TT,"127.0.0.1:1987"
67
- assign :name,:email, :gender=>'male', :age=>25
68
- end
69
- @jim = User.create(:name=>"jim", :email=>"jim@nonobo.com")
70
- @aaron = User.create(:name=>"aaron", :email=>"aaron@nonobo.com")
71
- @jack= User.create(:name=>"jack", :email=>"jack@nonbo.com")
72
- @lucy = User.create(:name=>"lucy", :email=>"lucy@nonobo.com")
73
- Useing CuteKV::Indexer module, you can build index for object, just like:
74
- CuteKV::Indexer::map(User=>[:name, :email, :age])
75
- then,
76
- User.indexes << @jim
77
- User.indexes << @aaron
78
- User.indexes << @lucy
79
- User.find_all_by_name("jim") #=>@jim
80
- User.find_all_by_age(25) #=>@jim, @aaron, @lucy, @jack
81
-
82
- == Supoort multiple database
83
- CuteKV using adapter to connect database.now backend support:TokyoCabinet/TokyoTyrant/LightCloud。
84
-
85
-
86
- == Using in rails
87
- in environment.rb, you will add
88
- require 'cutekv'
89
-
@@ -1,22 +0,0 @@
1
- # 访问LightCloud的加载模块
2
- require 'lightcloud'
3
- module CuteKV
4
- module Adapters
5
- module TokyoCloud
6
- def put(key, value)
7
- @db.set(key, value)
8
- end
9
-
10
- def get(key)
11
- @db.get(key)
12
- end
13
-
14
- private
15
- def establish(conf)
16
- conf = YAML.load_file(conf) if conf.is_a?(String)
17
- lookup_nodes, storage_nodes = LightCloud.generate_nodes(conf)
18
- @db = LightCloud.new(lookup_nodes, storage_nodes)
19
- end
20
- end
21
- end
22
- end
@@ -1,22 +0,0 @@
1
- # 访问TokyoTyrant的加载模块
2
- require 'rufus/tokyo'
3
- require 'cute_kv/adapters/tokyo_cabinet'
4
- module CuteKV
5
- module Adapters
6
- module TokyoTyrant
7
- include CuteKV::Adapters::TokyoCabinet
8
- private
9
- def establish(conf)
10
- if conf.is_a? Hash
11
- @host = conf[:host] || conf["host"]
12
- @port = (conf[:port] || conf["port"]).to_i
13
- else
14
- conf = conf.split(':')
15
- @host = conf[0]
16
- @port = conf[1].to_i
17
- end
18
- @db = Rufus::Tokyo::Tyrant.new(@host, @port)
19
- end
20
- end
21
- end
22
- end
@@ -1,285 +0,0 @@
1
- module CuteKV
2
- module Associations
3
-
4
- Map = Class.new
5
- Collection = Class.new(Array) {
6
- def to_json(options={})
7
- "[#{self.map{|c| c.to_json(options)}.join(',')}]"
8
- end
9
- }
10
-
11
- class Symmetry
12
-
13
- def initialize(asso={})
14
- @asso_string = parse(asso)
15
- @assos = @asso_string.split("#")
16
- end
17
-
18
- def mirror(object)
19
- m_o = @assos[@assos.size - 1 - @assos.index(object.to_s)]
20
- m_o = m_o.constantize if object.is_a? Class
21
- m_o = m_o.to_sym if object.is_a? Symbol
22
- m_o
23
- end
24
-
25
- def each
26
- asso = [[@assos[0].constantize, @assos[1].to_sym ],[@assos[-1].constantize, @assos[-2].to_sym]].uniq
27
- asso.each {|a| yield a[0], a[-1]}
28
- end
29
-
30
- private
31
- def parse(asso={})
32
- keys = asso.keys
33
- values = asso.values.flatten
34
- "#{keys[0]}##{values[0]}##{values[-1]}##{keys[-1]}"
35
- end
36
-
37
- end
38
-
39
- def self.included(base)
40
- base.send :include, InstanceMethods
41
- base.extend ClassMethods
42
- end
43
-
44
- module InstanceMethods
45
-
46
- def initialize(key, ids)
47
- @key_infos = key.split('#')
48
- @klass = @key_infos[-1].constantize
49
- @key = key
50
- @ids = deserialize ids
51
- end
52
-
53
- def ids
54
- @ids
55
- end
56
-
57
- def relex(object)
58
- r_k = @key_infos[0]
59
- r_v = @key_infos[1]
60
- k = @key_infos[-1]
61
- v = @key_infos[-2]
62
- key = "#{k}##{v}##{object.id}#relations##{r_v}##{r_k}"
63
- map = self.class.find(key) || self.class.create(key, [])
64
- end
65
-
66
-
67
- def objects
68
- map = self
69
- #it is very strange! when i use 'id', i can't use the method 'remove' correctly, so i use '_id'
70
- _id = @key_infos[2]
71
- _klass = @klass
72
- _rv = @key_infos[1]
73
- objs = Collection.new
74
- objs.replace self.ids.collect {|id| @klass.find(id)}.compact
75
- self.ids = objs.map(&:id) unless objs.size == self.ids.size
76
- Collection.class_eval {
77
- define_method(:<<){|object|
78
- return unless object.is_a? _klass
79
- if _rv.singular?
80
- map.send(:ids=, [object.id])
81
- else
82
- map.ids << object.id
83
- end
84
- rel_map = map.relex(object)
85
- rel_map.ids << _id
86
- map.save
87
- rel_map.save
88
- }
89
-
90
- define_method(:remove) {|object|
91
- return unless object.is_a? _klass
92
- map.ids.delete(object.id)
93
- rel_map = map.relex(object)
94
- rel_map.ids.delete(_id)
95
- map.save
96
- rel_map.save
97
- }
98
-
99
-
100
- }
101
- objs
102
- end
103
-
104
- def save
105
- self.class.backend[@key] = serialize @ids
106
- end
107
-
108
-
109
- private
110
- def ids=(ids)
111
- return unless ids.is_a? Array
112
- @ids = ids
113
- end
114
-
115
- def serialize(ids)
116
- self.class.send :serialize, ids
117
- end
118
-
119
- def deserialize(raw_ids)
120
- self.class.send :deserialize, raw_ids
121
- end
122
-
123
- end
124
-
125
-
126
- module ClassMethods
127
-
128
- def connect(class_obj)
129
- @backend = class_obj.backend
130
- @class_obj = class_obj
131
- end
132
-
133
- def find(key)
134
- new(key, @backend[key]) if @backend[key]
135
- end
136
-
137
- def create(key,ids=[])
138
- ids = serialize ids
139
- @backend[key] = ids
140
- new(key, ids)
141
- end
142
-
143
- def backend
144
- @backend
145
- end
146
-
147
- def find_or_create(key)
148
- find(key) || create(key, [])
149
- end
150
-
151
- def gen_key(k, v, object, r_v, r_k)
152
- key = "#{k}##{v}##{object.id}#relations##{r_v}##{r_k}"
153
- end
154
-
155
- def draw(k, v, object, r_v, r_k)
156
- key = gen_key(k, v, object, r_v, r_k)
157
- find_or_create(key)
158
- end
159
-
160
- private
161
-
162
- def serialize(ids)
163
- @class_obj.serialize(ids)
164
- end
165
-
166
- def deserialize(raw_ids)
167
- @class_obj.deserialize(raw_ids)
168
- end
169
-
170
- end
171
-
172
- class << self
173
- # Although relations between real word's objects are complex, we abstract all relations to three
174
- # type relations: # <tt>one_to_one</tt>, # <tt>one_to_many</tt>, # <tt>many_to_many</tt>
175
- #
176
- # == One_To_One
177
- # class User < ActiveObject::Base
178
- # assign :name, :gender=>"male"
179
- # end
180
- #
181
- # class Icon < ActiveObject::Base
182
- # assign :path
183
- # end
184
- # @aaron = User.create(:name=>"aaron")
185
- # @icon = Icon.create(:path=>"/tmp/aaron.jpg")
186
- #
187
- # Associations::map(User=>:icon, Icon=>:user)
188
- # User will add a instance method :icon
189
- # Icon will add a instance method :user
190
- # @aaron.icon = @icon
191
- # aaron = User.find(@aaron.id)
192
- # aaron.icon.path #=>"/tmp/aaron.jpg"
193
- # icon = Icon.find(@icon.id)
194
- # icon.user.name #=>"aaron"
195
- #
196
- # Associations::map(User=>[:wife, :husband])
197
- # @rita = User.create(:name=>"rita", :gender=>'female')
198
- # @aaron.wife = @rita
199
- # @aaron.wife #=>@rita
200
- # @rita.husband #=>@aaron
201
- #
202
- # == One_To_Many
203
- # Associations::map(User=>:books, Book=>:owner)
204
- # @book_ruby = Book.create(:name=>"Ruby")
205
- # @book_java = Book.create(:name=>"Java")
206
- #
207
- # == Many_To_Many
208
- # Associations::map(User=>:projects, Project=>:members)
209
- # @aaron = User.create(:name=>"aaron")
210
- # @nonobo = Project.create(:name=>"nonobo")
211
- # @admin = Project.create(:name=>"admin")
212
- # @aaron.prjects << @nonobo
213
- # @aaron.prjects << @admin
214
- # @aaron.projects #=>[@nonobo, @admin]
215
- # @nonobo.members #=>[@aaron]
216
- # @aaron.projects.remove(@nonbo)
217
- # @nonbo.members #=> []
218
- # @aaron.projects #=> [@admin]
219
- #
220
- #
221
- def map(asso)
222
- if asso.is_a? String
223
- #load classes's associations from yml file
224
- assos = YAML::load(IO.read(asso))
225
- assos.each {|asso| map(constantize_asso_keys(asso)) }
226
- else
227
- singus = Array(asso.delete(:singular)).compact
228
- Dic::SIN_WORDS.add(singus) unless singus.empty?
229
- pluras = Array(asso.delete(:plural)).compact
230
- Dic::PLU_WORDS.add(pluras) unless pluras.empty?
231
- symmetry = Symmetry.new(asso)
232
- symmetry.each {|k,v|
233
- r_k = symmetry.mirror(k)
234
- r_v = symmetry.mirror(v)
235
- asso_map = Map.send(:include, self)
236
- asso_map.connect(k)
237
- k.class_eval {
238
- define_method(v) {
239
- map = asso_map.draw(k,v,self,r_v,r_k)
240
- if v.singular?
241
- obj = map.objects.last
242
- return if obj.nil?
243
- def obj.remove(object)
244
- Collection.new.replace([self]).remove(object)
245
- end
246
- obj
247
- else
248
- map.objects
249
- end
250
- }
251
-
252
- define_method("#{v}=") {|object|
253
- return if object.nil?
254
- map = asso_map.draw(k,v,self,r_v,r_k)
255
- vo = self.send(v)
256
- vo.send(r_v).remove(self) if vo
257
- rvo = object.send(r_v)
258
- rvo.send(v).remove(object) if r_v.singular? && rvo
259
- map.objects << object
260
- } if v.singular?
261
-
262
- }
263
- }
264
- end
265
-
266
- end
267
-
268
- protected
269
-
270
- def constantize_asso_keys(asso)
271
- h = {}
272
- plurs = asso.delete("plural").split(" ") if asso["plural"]
273
- sins = asso.delete("singular").split(" ") if asso["singular"]
274
- h[:plural] = plurs if plurs
275
- h[:singular] = sins if sins
276
- asso.each {|k,v| h[k.constantize] = v.split(' ') }
277
- h
278
- end
279
-
280
- end
281
-
282
- end
283
-
284
-
285
- end