kangaroo 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. data/.gitignore +1 -0
  2. data/.rspec +2 -0
  3. data/.yardopts +6 -0
  4. data/Gemfile +2 -0
  5. data/Gemfile.lock +66 -0
  6. data/LICENSE +22 -0
  7. data/README.md +65 -0
  8. data/Rakefile +36 -0
  9. data/config/kangaroo.yml.sample +12 -0
  10. data/docs/AdditionalServices.md +3 -0
  11. data/docs/Architecture.md +50 -0
  12. data/docs/Installation.md +73 -0
  13. data/docs/Usage.md +161 -0
  14. data/features/connection.feature +5 -0
  15. data/features/env.rb +8 -0
  16. data/features/step_definitions/basic_steps.rb +24 -0
  17. data/features/step_definitions/connection_steps.rb +13 -0
  18. data/features/support/test.yml +11 -0
  19. data/features/utility_services.feature +39 -0
  20. data/kangaroo.gemspec +29 -0
  21. data/lib/kangaroo.rb +6 -0
  22. data/lib/kangaroo/exception.rb +7 -0
  23. data/lib/kangaroo/model/attributes.rb +124 -0
  24. data/lib/kangaroo/model/base.rb +70 -0
  25. data/lib/kangaroo/model/condition_normalizer.rb +63 -0
  26. data/lib/kangaroo/model/default_attributes.rb +22 -0
  27. data/lib/kangaroo/model/field.rb +20 -0
  28. data/lib/kangaroo/model/finder.rb +92 -0
  29. data/lib/kangaroo/model/inspector.rb +55 -0
  30. data/lib/kangaroo/model/open_object_orm.rb +117 -0
  31. data/lib/kangaroo/model/persistence.rb +180 -0
  32. data/lib/kangaroo/model/relation.rb +212 -0
  33. data/lib/kangaroo/model/remote_execute.rb +29 -0
  34. data/lib/kangaroo/railtie.rb +13 -0
  35. data/lib/kangaroo/ruby_adapter/base.rb +28 -0
  36. data/lib/kangaroo/ruby_adapter/class_definition.rb +46 -0
  37. data/lib/kangaroo/ruby_adapter/fields.rb +18 -0
  38. data/lib/kangaroo/util/client.rb +59 -0
  39. data/lib/kangaroo/util/configuration.rb +82 -0
  40. data/lib/kangaroo/util/database.rb +92 -0
  41. data/lib/kangaroo/util/loader.rb +98 -0
  42. data/lib/kangaroo/util/loader/model.rb +21 -0
  43. data/lib/kangaroo/util/loader/namespace.rb +15 -0
  44. data/lib/kangaroo/util/proxy.rb +35 -0
  45. data/lib/kangaroo/util/proxy/common.rb +111 -0
  46. data/lib/kangaroo/util/proxy/db.rb +34 -0
  47. data/lib/kangaroo/util/proxy/object.rb +153 -0
  48. data/lib/kangaroo/util/proxy/report.rb +24 -0
  49. data/lib/kangaroo/util/proxy/superadmin.rb +71 -0
  50. data/lib/kangaroo/util/proxy/wizard.rb +25 -0
  51. data/lib/kangaroo/util/proxy/workflow.rb +14 -0
  52. data/lib/kangaroo/version.rb +3 -0
  53. data/spec/model/attributes_spec.rb +70 -0
  54. data/spec/model/base_spec.rb +19 -0
  55. data/spec/model/default_attributes_spec.rb +37 -0
  56. data/spec/model/finder_spec.rb +104 -0
  57. data/spec/model/inspector_spec.rb +56 -0
  58. data/spec/model/open_object_orm_spec.rb +134 -0
  59. data/spec/model/persistence_spec.rb +53 -0
  60. data/spec/model/relation_spec.rb +122 -0
  61. data/spec/ruby_adapter/class_definition_spec.rb +51 -0
  62. data/spec/server_helper.rb +167 -0
  63. data/spec/spec_helper.rb +14 -0
  64. data/spec/test_env/test.yml +11 -0
  65. data/spec/util/configuration_spec.rb +36 -0
  66. data/spec/util/loader_spec.rb +50 -0
  67. data/spec/util/proxy_spec.rb +61 -0
  68. metadata +260 -0
@@ -0,0 +1 @@
1
+ .yardoc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
@@ -0,0 +1,6 @@
1
+ --no-private
2
+ -
3
+ docs/Installation.md
4
+ docs/Usage.md
5
+ LICENSE
6
+ README.md
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubygems
2
+ gemspec
@@ -0,0 +1,66 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ kangaroo (0.0.1)
5
+ activerecord (>= 3.0.0)
6
+ activesupport (>= 3.0.0)
7
+ rapuncel (~> 0.0.2)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ activemodel (3.0.3)
13
+ activesupport (= 3.0.3)
14
+ builder (~> 2.1.2)
15
+ i18n (~> 0.4)
16
+ activerecord (3.0.3)
17
+ activemodel (= 3.0.3)
18
+ activesupport (= 3.0.3)
19
+ arel (~> 2.0.2)
20
+ tzinfo (~> 0.3.23)
21
+ activesupport (3.0.3)
22
+ arel (2.0.7)
23
+ builder (2.1.2)
24
+ columnize (0.3.2)
25
+ cucumber (0.10.0)
26
+ builder (>= 2.1.2)
27
+ diff-lcs (~> 1.1.2)
28
+ gherkin (~> 2.3.2)
29
+ json (~> 1.4.6)
30
+ term-ansicolor (~> 1.0.5)
31
+ diff-lcs (1.1.2)
32
+ gherkin (2.3.3)
33
+ json (~> 1.4.6)
34
+ i18n (0.5.0)
35
+ json (1.4.6)
36
+ linecache (0.43)
37
+ nokogiri (1.4.4)
38
+ rapuncel (0.0.2)
39
+ activesupport (>= 3.0.0)
40
+ nokogiri
41
+ rspec (2.4.0)
42
+ rspec-core (~> 2.4.0)
43
+ rspec-expectations (~> 2.4.0)
44
+ rspec-mocks (~> 2.4.0)
45
+ rspec-core (2.4.0)
46
+ rspec-expectations (2.4.0)
47
+ diff-lcs (~> 1.1.2)
48
+ rspec-mocks (2.4.0)
49
+ ruby-debug (0.10.4)
50
+ columnize (>= 0.1)
51
+ ruby-debug-base (~> 0.10.4.0)
52
+ ruby-debug-base (0.10.4)
53
+ linecache (>= 0.3)
54
+ term-ansicolor (1.0.5)
55
+ tzinfo (0.3.24)
56
+ yard (0.6.4)
57
+
58
+ PLATFORMS
59
+ ruby
60
+
61
+ DEPENDENCIES
62
+ cucumber
63
+ kangaroo!
64
+ rspec
65
+ ruby-debug
66
+ yard
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2010-2011 ['Marian Theisen', 'Michael Eickenberg']
2
+
3
+ Permission is hereby granted, free of charge, to any person
4
+ obtaining a copy of this software and associated documentation
5
+ files (the "Software"), to deal in the Software without
6
+ restriction, including without limitation the rights to use,
7
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the
9
+ Software is furnished to do so, subject to the following
10
+ conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,65 @@
1
+ Kangaroo
2
+ ========
3
+
4
+ Overview
5
+ --------
6
+
7
+ Kangaroo is an OpenObject client/wrapper for Rails 3, based on ActiveModel. It provides CRUD access to OpenERP objects via XMLRPC.
8
+ It's fast and provides default data for new objects.
9
+
10
+ Installation
11
+ ------------
12
+
13
+ If you're on Rails 3, just add Kangaroo to your Gemfile:
14
+
15
+ gem 'kangaroo'
16
+
17
+ And create a **kangaroo.yml** configuration file in **[RAILS\_ROOT]/config**, containing these options:
18
+
19
+ host: 127.0.0.1
20
+ port: 8069
21
+
22
+ database:
23
+ name: my_openerp
24
+ user: admin
25
+ password: admin
26
+
27
+ models:
28
+ - account.*
29
+ - product.*
30
+ - res.company
31
+
32
+ Adjust your connection and database settings and specify the models you need.
33
+
34
+ Usage
35
+ -----
36
+
37
+ OpenObject models are mapped to ruby classes:
38
+
39
+ Oo::Res::Country
40
+ # represents 'res.country'
41
+
42
+ Oo::Product::Product
43
+ # represents 'product.product'
44
+
45
+ Oo::Sale::Order::Line
46
+ # represents 'sale.order.line
47
+
48
+ You can use this models like ActiveRecord models:
49
+
50
+ country = Oo::Res::Country.find 1
51
+ country = Oo::Res::Country.where(:code => 'DE').first
52
+
53
+ country.name = "Schland"
54
+ country.save
55
+
56
+ country.reload
57
+
58
+ countries = Oo::Res::Country.limit(100).all
59
+ countries = Oo::Res::Country.limit(100).order('code').all
60
+
61
+ Oo::Res::Country.create :code => 'DE', :name => 'Germany'
62
+
63
+ etc.
64
+ Please refer to {file:docs/Usage.md Usage} to learn about limitations/features not yet
65
+ implemented.
@@ -0,0 +1,36 @@
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+ require 'bundler'
4
+
5
+ Bundler::GemHelper.install_tasks
6
+
7
+ #TODO: sdoc
8
+ desc 'Generate KangARoo rdoc.'
9
+ Rake::RDocTask.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'KangARoo'
12
+ rdoc.options << '--line-numbers' << '--inline-source'
13
+ rdoc.rdoc_files.include('README')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ begin
18
+ require 'rspec/core/rake_task'
19
+ desc 'Run RSpec suite.'
20
+ RSpec::Core::RakeTask.new('spec')
21
+ rescue LoadError
22
+ puts "RSpec is not available. In order to run specs, you must: gem install rspec"
23
+ end
24
+
25
+ begin
26
+ require 'cucumber/rake/task'
27
+ desc "Run Cucumber features."
28
+ Cucumber::Rake::Task.new(:features)
29
+ rescue LoadError
30
+ puts "Cucumber is not available. In order to run features, you must: gem install cucumber"
31
+ end
32
+
33
+
34
+
35
+ # If you want to make this the default task
36
+ task :default => :spec
@@ -0,0 +1,12 @@
1
+ host: 127.0.0.1
2
+ port: 8069
3
+
4
+ database:
5
+ name: my_openerp
6
+ user: admin
7
+ password: admin
8
+
9
+ models:
10
+ - account.*
11
+ - product.*
12
+ - res.company
@@ -0,0 +1,3 @@
1
+ Additional Services
2
+ ===================
3
+
@@ -0,0 +1,50 @@
1
+ Architecture
2
+ ============
3
+
4
+ #### Index
5
+ {file:README.md Readme}
6
+ {file:docs/Installation.md Installation}
7
+ {file:docs/Usage.md Usage}
8
+ {file:docs/Architecture.md Architecture}
9
+ {file:docs/AdditionalServices.md Additional Services}
10
+
11
+
12
+ Components
13
+ ----------
14
+ Kangaroo mainly consists of 3 parts:
15
+
16
+ * **Util** contains everything needed to establish and use a connection to an OpenERP server.
17
+ Use {Kangaroo::Util::Configuration} to configure a connection to a database, and
18
+ {Kangaroo::Util::Loader} to load the models you need.
19
+ * **RubyAdapyer** is a mini-framework to convert OpenObject models to ruby. It's responsible
20
+ of creating the neccessary modules and classes to use i.e. the "product.product" model
21
+ via Oo::Product::Product
22
+ * **Model** is the base class for all OpenObject models, and is responsible for all runtime
23
+ behavior.
24
+
25
+
26
+
27
+ Communication
28
+ -------------
29
+
30
+ ### Proxies
31
+ The lowest level of communication happens over {Kangaroo::Util::Proxy} and its subclasses. They
32
+ proxy method calls to the XML-RPC services the OpenERP server provides.
33
+
34
+ ### OpenObject ORM
35
+ Suppose you have a Ruby model for an OpenObject model **Oo::Res::Country** (either via directly subclassing {Kangaroo::Model::Base},
36
+ or via {Kangaroo::Util::Loader}), you can access the OpenObject ORM API directly:
37
+
38
+ Oo::Res::Country.search(...)
39
+ Oo::Res::Country.read(...)
40
+ Oo::Res::Country.fields_get(...)
41
+ Oo::Res::Country.default_get(...)
42
+ Oo::Res::Country.unlink(...)
43
+
44
+ The **create** and **write** are named **create\_record** and **write\_record**
45
+
46
+ Oo::Res::Country.create_record(...)
47
+ Oo::Res::Country.write_record(...)
48
+
49
+ ### ActiveRecord-ish ORM
50
+ see {file:docs/Usage.md Usage}
@@ -0,0 +1,73 @@
1
+ Installation
2
+ ============
3
+
4
+ #### Index
5
+ {file:README.md Readme}
6
+ {file:docs/Installation.md Installation}
7
+ {file:docs/Usage.md Usage}
8
+ {file:docs/Architecture.md Architecture}
9
+ {file:docs/AdditionalServices.md Additional Services}
10
+
11
+ Rails 3
12
+ -------
13
+ If you're on Rails 3, just add Kangaroo to your Gemfile:
14
+
15
+ gem 'kangaroo'
16
+
17
+ And run
18
+
19
+ bundle install
20
+
21
+ Create a **kangaroo.yml** configuration file in **[RAILS\_ROOT]/config**, containing these options:
22
+
23
+ host: 127.0.0.1
24
+ port: 8069
25
+
26
+ database:
27
+ name: my_openerp
28
+ user: admin
29
+ password: admin
30
+
31
+ models:
32
+ - account.*
33
+ - product.*
34
+ - res.company
35
+
36
+ Adjust your connection and database settings, specify the models you wish to get loaded, and you're good to go!
37
+ Checkout the usage doc {file:docs/Usage.md Usage}
38
+
39
+ General Ruby
40
+ ------------
41
+ Install the gem via
42
+
43
+ gem install kangaroo
44
+
45
+ Now you need to configure Kangaroo. You can either use a YAML configuration file (see **Rails 3**) or
46
+ pass a Hash with configuration options.
47
+
48
+ via file
49
+
50
+ config = Kangaroo::Util::Configuration.new 'some_config_file.yml'
51
+ config.load_models
52
+
53
+
54
+ via Hash
55
+
56
+ config_hash = {
57
+ :host => 'localhost',
58
+ :port => 8069,
59
+
60
+ :database => {
61
+ :name => 'my_openerp',
62
+ :user => 'admin',
63
+ :password => 'admin',
64
+
65
+ :models => %w(account.* product.* res.company)
66
+ }
67
+ }
68
+
69
+ config = Kangaroo::Util::Configuration.new config_hash
70
+ config.load_models
71
+
72
+ The connection should be setup now, and the models ready to use.
73
+
@@ -0,0 +1,161 @@
1
+ Usage
2
+ =====
3
+
4
+ #### Index
5
+ {file:README.md Readme}
6
+ {file:docs/Installation.md Installation}
7
+ {file:docs/Usage.md Usage}
8
+ {file:docs/Architecture.md Architecture}
9
+ {file:docs/AdditionalServices.md Additional Services}
10
+
11
+ Basics
12
+ ------
13
+ Kangaroo-wrapped OpenObject models provides an ActiveRecord-ish API to find, create and update records.
14
+ But please keep in mind, that due to the fundamental differences between a SQL database and the OpenObject
15
+ ORM / XML-RPC service. And some things we're saving up for upcoming versions.
16
+
17
+ ### Querying
18
+ #### Find
19
+ The most basic query method, as in ActiveRecord is {Kangaroo::Model::Finder#find find}, wich reads record(s)
20
+ by id(s):
21
+
22
+ Oo::Res::Country.find 1
23
+ # => <Oo::Res::Country id: 1 ....>
24
+
25
+ Oo::Res::Country.find [1, 2]
26
+ # => [<Oo::Res::Country id: 1 ....>, <Oo::Res::Country id: 2 ....>]
27
+
28
+ Additionally the classic keywords for *find* can be used:
29
+
30
+ Oo::Res::Country.find :first
31
+ Oo::Res::Country.find :last
32
+ Oo::Res::Country.find :all
33
+
34
+ #### First / All / Last
35
+ Shorter than *find(keyword)* are definitely {Kangaroo::Model::Finder#first first}, {Kangaroo::Model::Finder#all all}, {Kangaroo::Model::Finder#last last}:
36
+
37
+ Oo::Res::Country.first
38
+ Oo::Res::Country.last
39
+ Oo::Res::Country.all
40
+
41
+ #### Relation-like querying
42
+ Kangaroo somewhat tries to emulate ActiveRecords great ARel query interface, so you can specify
43
+ conditions via **where**:
44
+
45
+ Oo::Res::Country.where(:code => 'DE').first
46
+ # => <Oo::Res::Country id: 42, code: 'DE', name: 'Germany'>
47
+
48
+ **limit** and **offset**:
49
+
50
+ Oo::Res::Country.offset(10).limit(2).all
51
+ # => [<Oo::Res::Country id: 11 ....>, <Oo::Res::Country id: 12 ....>]
52
+
53
+ **context**:
54
+
55
+ Oo::Res::Country.context(:lang => 'de_DE').first
56
+ # => <Oo::Res::Country id: 42, code: 'DE', name: 'Deutschland'>
57
+
58
+ read only some fields with **select**:
59
+
60
+ Oo::Res::Country.select('code').first
61
+ # => <Oo::Res::Country id: 42, code: 'DE', name: nil>
62
+
63
+ order the results with **order**:
64
+
65
+ Oo::Res::Country.order(:name).all
66
+
67
+ # Or if you wish descending order
68
+ Oo::Res::Country.order(:name, true).all
69
+
70
+ additionally, there is **reverse**, which reverses all prior **order** clauses
71
+ (or adds an **order('id', true)**)
72
+
73
+ Oo::Res::Country.reverse.all
74
+ # => [<Oo::Res::Country id: 245 ....>, <Oo::Res::Country id: 244 ....>]
75
+
76
+ #### A note about "*where*"
77
+ The OpenObject ORM expects conditions as an Array like this:
78
+
79
+ Oo::Res::Country.where(['code', '=', 'DE']).first
80
+
81
+ As this can be quite cumbersome to use, Kangaroo accepts conditions as Strings, which will simply be
82
+ splitted in an Array
83
+
84
+ Oo::Res::Country.where('a = one').first
85
+
86
+ This implies that you can't specify complex conditions via Strings, this is only to simplify simple conditions.
87
+ As shown before, also Hash conditions work:
88
+
89
+ Oo::Res::Country.where(:code => 'DE').first
90
+
91
+ # Or if you use an Array Kangaroo will switch to the **in** operator
92
+ Oo::Res::Country.where(:code => ['DE', 'EN']).all
93
+
94
+
95
+ ### Working with records
96
+ #### Attributes
97
+ All OpenObject fields are accessible via getters and setters:
98
+
99
+ record = Oo::Res::Country.where(:code => 'DE').first
100
+ record.name
101
+ # => "Germany"
102
+
103
+ record.name = "Dschoermany"
104
+ record.name
105
+ # => "Dschoermany"
106
+
107
+ Of course those attributes can be persisted
108
+
109
+ record.save
110
+ record.reload
111
+ record.name
112
+ # => "Dschoermany"
113
+
114
+ #### Dirty
115
+ Kangaroo includes ActiveModel::Dirty to keep track of changes:
116
+
117
+ record = Oo::Res::Country.where(:code => 'DE').first
118
+ record.name
119
+ # => "Germany"
120
+
121
+ record.name = "Dschoermany"
122
+ record.changed?
123
+ # => true
124
+
125
+ record.name_was
126
+ # => "Germany"
127
+
128
+ #### Creating records
129
+ If you initialize a new record, Kangaroo fetches the default values for this model
130
+
131
+ record = Oo::Res::User.new
132
+ record.context_lang
133
+ # => 'en_US'
134
+ record.context_lang_changed?
135
+ # => true
136
+
137
+ #### Destroying records
138
+
139
+ Oo::Res::User.first.destroy
140
+
141
+
142
+ #### Misc
143
+ Kangaroo also supports
144
+
145
+ ##### new\_record? / persisted?
146
+
147
+ record = Oo::Res::User.new
148
+ record.new_record?
149
+ # => true
150
+
151
+ record.persisted?
152
+ # => false
153
+
154
+ ##### destroyed?
155
+
156
+ record = Oo::Res::Country.first
157
+ record.destroy
158
+ record.destroyed?
159
+ # => true
160
+
161
+