kangaroo 0.0.1.pre

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 (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
+