restfulx 1.2.5 → 1.3.0

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 (52) hide show
  1. data/README.rdoc +3 -3
  2. data/Rakefile +17 -2
  3. data/VERSION.yml +2 -3
  4. data/bin/rx-gen +1 -1
  5. data/ext/restfulx/ext/amf/serializer/extconf.rb +3 -0
  6. data/lib/restfulx.rb +43 -81
  7. data/lib/restfulx/active_record_tasks.rb +8 -6
  8. data/lib/restfulx/active_record_uuid_helper.rb +9 -10
  9. data/lib/restfulx/amf.rb +14 -0
  10. data/lib/restfulx/amf/class_mapping.rb +106 -0
  11. data/lib/restfulx/amf/ext.rb +11 -0
  12. data/lib/restfulx/amf/ext/serializer.bundle +0 -0
  13. data/lib/restfulx/amf/pure.rb +11 -0
  14. data/lib/restfulx/amf/pure/io_helpers.rb +52 -0
  15. data/lib/restfulx/amf/pure/serializer.rb +304 -0
  16. data/lib/restfulx/configuration.rb +16 -12
  17. data/lib/restfulx/{rails/recipes.rb → recipes.rb} +1 -2
  18. data/lib/restfulx/rx_action_controller.rb +34 -0
  19. data/lib/restfulx/rx_active_record.rb +360 -0
  20. data/lib/restfulx/rx_active_support.rb +139 -0
  21. data/lib/restfulx/{datamapper_foo.rb → rx_datamapper.rb} +0 -2
  22. data/lib/restfulx/{rails/schema_to_yaml.rb → schema_to_rx_yaml.rb} +88 -5
  23. data/lib/restfulx/swf_helper.rb +61 -0
  24. data/lib/restfulx/tasks.rb +5 -3
  25. data/rails_generators/rx_config/rx_config_generator.rb +2 -2
  26. data/rails_generators/rx_config/templates/mainapp.mxml +1 -1
  27. data/rails_generators/rx_config/templates/restfulx.erb +5 -3
  28. data/rails_generators/rx_main_app/rx_main_app_generator.rb +2 -2
  29. data/rails_generators/rx_scaffold/rx_scaffold_generator.rb +7 -7
  30. data/rails_generators/rx_yaml_scaffold/rx_yaml_scaffold_generator.rb +5 -3
  31. data/rxgen_generators/rx_config/rx_config_generator.rb +1 -1
  32. data/test/rails/fixtures/locations.yml +5 -6
  33. data/test/rails/fixtures/notes.yml +5 -15
  34. data/test/rails/fixtures/projects.yml +7 -23
  35. data/test/rails/fixtures/tasks.yml +17 -43
  36. data/test/rails/fixtures/users.yml +7 -11
  37. data/test/rails/helpers/functional_test_helper.rb +5 -4
  38. data/test/rails/helpers/performance_test_helper.rb +5 -0
  39. data/test/rails/helpers/test_helper.rb +27 -0
  40. data/test/rails/helpers/unit_test_helper.rb +3 -15
  41. data/test/rails/test_active_foo.rb +21 -25
  42. data/test/rails/{test_rails_integration_functional.rb → test_notes_controller_functional.rb} +5 -5
  43. data/test/rails/test_serialiazation_performance.rb +32 -0
  44. data/test/rails/test_to_amf.rb +30 -0
  45. data/test/rails/test_to_fxml.rb +18 -15
  46. data/test/rails/test_to_json.rb +2 -14
  47. metadata +30 -19
  48. data/lib/restfulx/active_foo.rb +0 -178
  49. data/lib/restfulx/rails/schema_to_yaml/extensions/enumerable.rb +0 -8
  50. data/lib/restfulx/rails/schema_to_yaml/settings/config.rb +0 -17
  51. data/lib/restfulx/rails/schema_to_yaml/settings/core.rb +0 -73
  52. data/lib/restfulx/rails/swf_helper.rb +0 -59
data/README.rdoc CHANGED
@@ -19,7 +19,7 @@ Here's some of the things you can do with *RestfulX*:
19
19
  that use _ActiveRecord_, _DataMapper_, _CouchRest_, _ActiveCouch_ and so on.
20
20
 
21
21
  * *Communicate* between your Flex/AIR Rich Internet Application and service providers
22
- using either _XML_ or _JSON_.
22
+ using either _AMF_, _XML_ or _JSON_.
23
23
 
24
24
  * *Persist* your data directly in Adobe AIR _SQLite_ database or _CouchDB_
25
25
  without any additional infrastructure or intermediate servers.
@@ -33,7 +33,7 @@ Here's some of the things you can do with *RestfulX*:
33
33
 
34
34
  For details on how to get started with the RestfulX framework refer to:
35
35
 
36
- http://restfulx.org
36
+ http://restfulx.github.com
37
37
 
38
38
  == Getting Involved
39
39
 
@@ -47,4 +47,4 @@ Get involved with the community:
47
47
 
48
48
  == License
49
49
 
50
- Copyright (c) 2008-2009 Dima Berastau and Contributors, released under MIT License
50
+ Copyright (c) 2008-2010 Dima Berastau and Contributors, released under MIT License
data/Rakefile CHANGED
@@ -5,6 +5,7 @@ begin
5
5
  Jeweler::Tasks.new do |gem|
6
6
  gem.name = "restfulx"
7
7
  gem.summary = "RestfulX Framework Code Generation Engine / Rails 2.1+ Integration Support"
8
+ gem.description = "RestfulX: The RESTful Way to develop Adobe Flex and AIR applications"
8
9
  gem.email = "dima.berastau@gmail.com"
9
10
  gem.homepage = "http://restfulx.org"
10
11
  gem.rubyforge_project = "restfulx"
@@ -12,19 +13,33 @@ begin
12
13
  gem.files = FileList["[A-Z]*", "{bin,app_generators,rails_generators,rxgen_generators,lib,test,spec,tasks}/**/*"]
13
14
  gem.files.exclude 'test/**/*.log', 'test/**/*.sqlite3'
14
15
  gem.test_files.exclude 'test/**/*.log', 'test/**/*.sqlite3'
15
- gem.add_dependency('rubigen', '>= 1.5.0')
16
+ gem.add_dependency('rubigen', '>= 1.5.2')
16
17
  gem.add_dependency('activesupport', '>=2.0.0')
17
18
  end
19
+
20
+ Jeweler::RubyforgeTasks.new do |rubyforge|
21
+ rubyforge.doc_task = "rdoc"
22
+ end
18
23
  rescue LoadError
19
24
  puts "jeweler not available. Install it with: sudo gem install jeweler"
20
25
  end
21
26
 
27
+ require 'rake/extensiontask'
28
+ Rake::ExtensionTask.new do |ext|
29
+ ext.name = 'serializer'
30
+ ext.gem_spec = Rake.application.jeweler_tasks.gemspec
31
+ # ext.cross_compile = true
32
+ # ext.cross_platform = %w[i386-mswin32 i386-mingw32]
33
+ ext.ext_dir = 'ext/restfulx/ext/amf/serializer'
34
+ ext.lib_dir = 'lib/restfulx/amf/ext'
35
+ end
36
+
22
37
  require 'rake/rdoctask'
23
38
  Rake::RDocTask.new do |rdoc|
24
39
  config = YAML.load(File.read('VERSION.yml'))
25
40
  rdoc.rdoc_dir = 'doc/api'
26
41
  rdoc.title = "RestfulX #{config[:major]}.#{config[:minor]}.#{config[:patch]}"
27
- rdoc.options << '--line-numbers' << '--inline-source' #<< '-Tjamis'
42
+ rdoc.options << '--line-numbers' << '--inline-source' # << '-Tjamis'
28
43
  rdoc.rdoc_files.include('README*')
29
44
  rdoc.rdoc_files.include('lib/**/*.rb')
30
45
  end
data/VERSION.yml CHANGED
@@ -1,5 +1,4 @@
1
1
  ---
2
- :patch: 5
3
- :build:
4
2
  :major: 1
5
- :minor: 2
3
+ :minor: 3
4
+ :patch: 0
data/bin/rx-gen CHANGED
@@ -22,7 +22,7 @@ require 'rubigen'
22
22
  require File.join(File.dirname(__FILE__), '..', 'lib', 'restfulx')
23
23
 
24
24
  if %w(-v --version).include? ARGV.first
25
- puts "#{File.basename($0)} #{RestfulX::FRAMEWORK_VERSION}"
25
+ puts "#{File.basename($0)} #{RestfulX::VERSION}"
26
26
  exit(0)
27
27
  end
28
28
 
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile 'restfulx/ext/amf/serializer'
data/lib/restfulx.rb CHANGED
@@ -1,90 +1,52 @@
1
- # Sets up all the relevant configuration options and brings together
2
- # patches for Rails, Merb, ActiveRecord and Data Mapper.
3
- #
4
- # Loads RestfulX specific rake tasks if appropriate.
5
- module RestfulX
6
-
7
- # :stopdoc:
8
- FRAMEWORK_VERSION = '1.2.5'
9
- LIB_DIR = File.join(File.dirname(__FILE__), 'restfulx/')
10
- # :startdoc:
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+ require 'yaml'
3
+ require 'restfulx/configuration'
11
4
 
12
- # Utility method used to require all files ending in .rb that lie in the
13
- # directory below this file that has the same name as the filename passed
14
- # in. Optionally, a specific _directory_ name can be passed in such that
15
- # the _filename_ does not have to be equivalent to the directory.
16
- #
17
- def self.require_all_libs_relative_to( fname, dir = nil )
18
- dir ||= ::File.basename(fname, '.*')
19
- search_me = ::File.expand_path(
20
- ::File.join(::File.dirname(fname), dir, '*', '*.rb'))
21
-
22
- Dir.glob(search_me).sort.each {|rb| require rb}
5
+ # Settings
6
+ module RestfulX
7
+ # Valid types supported internally on top of standard Rails types
8
+ module Types
9
+ APPLICATION_FXML = 'application/xml'.freeze
10
+ APPLICATION_AMF = 'application/x-amf'.freeze
11
+ end
12
+
13
+ # get the currently defined AMF serializer
14
+ def self.amf_serializer
15
+ @amf_serializer
16
+ end
17
+
18
+ # set the amf serializer to use
19
+ # valid options are :native and :pure, using :pure is recommended as it is as fast
20
+ # as native but currently better tested/supported
21
+ def self.amf_serializer=(value)
22
+ @amf_serializer = value
23
23
  end
24
- end
25
24
 
26
- require RestfulX::LIB_DIR + 'configuration'
25
+ VERSION_SOURCE = YAML.load(File.read(File.join(File.dirname(__FILE__), '..', 'VERSION.yml')))
26
+ VERSION = "#{VERSION_SOURCE[:major]}.#{VERSION_SOURCE[:minor]}.#{VERSION_SOURCE[:patch]}"
27
+ end
27
28
 
28
- # make sure we're running inside Merb
29
- if defined?(Merb::Plugins)
30
- Merb::Plugins.add_rakefiles RestfulX::LIB_DIR + 'tasks'
29
+ # ActiveRecord extensions
30
+ if defined?(ActiveRecord::Base)
31
+ ['rx_active_support', 'rx_active_record'].each { |lib| require "restfulx/#{lib}" }
32
+ ActiveRecord::Base.send :include,
33
+ RestfulX::ActiveRecord unless ActiveRecord::Base.included_modules.include?(RestfulX::ActiveRecord)
34
+ end
31
35
 
32
- Merb::BootLoader.before_app_loads do
33
-
34
- if defined?(ActiveRecord::Base)
35
- Merb.add_mime_type(:fxml, :to_fxml, %w[application/xml text/xml application/x-xml], :charset => "utf-8")
36
- ['active_foo', 'active_record_default_methods'].each { |lib| require RestfulX::LIB_DIR + lib }
37
- Merb::Plugins.add_rakefiles RestfulX::LIB_DIR + 'active_record_tasks'
38
- else
39
- Merb.add_mime_type(:fxml, :to_xml, %w[application/xml text/xml application/x-xml], :charset => "utf-8")
40
- if defined?(Merb::Orms::DataMapper)
41
- require RestfulX::LIB_DIR + 'datamapper_foo'
42
- end
43
- end
44
- end
45
- elsif defined?(ActionController::Base)
46
- # if we are not running in Merb, try to hook up Rails
47
- Mime::Type.register_alias "application/xml", :fxml
36
+ # ActionController/ActionView extensions
37
+ if defined?(ActionController::Base)
38
+ Mime::Type.register_alias RestfulX::Types::APPLICATION_FXML, :fxml
39
+ Mime::Type.register RestfulX::Types::APPLICATION_AMF, :amf
48
40
 
49
- ['active_foo', 'rails/swf_helper', 'rails/schema_to_yaml'].each { |lib| require RestfulX::LIB_DIR + lib }
50
-
51
- ActionView::Base.send :include, SWFHelper unless ActionView::Base.included_modules.include?(SWFHelper)
52
- ActiveRecord::Migration.send :include, SchemaToYaml
41
+ ['rx_action_controller', 'swf_helper'].each { |lib| require "restfulx/#{lib}" }
53
42
 
54
- # We mess with default +render+ implementation a bit to add support for expressions
55
- # such as format.fxml { render :fxml => @foo }
56
- module ActionController
57
- # Override render to add support for render :fxml
58
- class Base
59
- alias_method :old_render, :render unless method_defined?(:old_render)
43
+ ActionController::Base.send :include,
44
+ RestfulX::ActionController unless ActionController::Base.included_modules.include?(RestfulX::ActionController)
45
+ ActionView::Base.send :include,
46
+ RestfulX::SWFHelper unless ActionView::Base.included_modules.include?(RestfulX::SWFHelper)
47
+ end
60
48
 
61
- # so that we can have handling for :fxml option and write code like
62
- # format.fxml { render :fxml => @projects }
63
- def render(options = nil, extra_options = {}, &block)
64
- if options.is_a?(Hash) && options[:fxml]
65
- xml = options[:fxml]
66
- response.content_type ||= Mime::XML
67
- render_for_text(xml.respond_to?(:to_fxml) ? xml.to_fxml : xml, options[:status])
68
- else
69
- old_render(options, extra_options, &block)
70
- end
71
- end
72
- end
73
- end
74
-
75
- module ActiveRecord
76
- # ActiveRecord named scopes are computed *before* restfulx gem gets loaded
77
- # this patch addresses that and makes sure +to_fxml+ calls are properly
78
- # delegated
79
- module NamedScope
80
- # make sure we properly delegate +to_fxml+ calls to the proxy
81
- class Scope
82
- delegate :to_fxml, :to => :proxy_found
83
- end
84
- end
85
- end
86
- elsif defined?(DataMapper)
87
- require RestfulX::LIB_DIR + 'datamapper_foo'
88
- elsif defined?(ActiveRecord::Base)
89
- require RestfulX::LIB_DIR + 'active_foo'
49
+ # DataMapper extensions
50
+ if defined?(DataMapper)
51
+ require 'restfulx/rx_datamapper'
90
52
  end
@@ -1,12 +1,14 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+
1
3
  # ActiveRecord specific Rake tasks. Namely, nice little extras such as:
2
4
  # - db:mysql:stage
3
5
  # - db:refresh
4
- require File.join(File.dirname(__FILE__), 'tasks')
5
- require File.join(File.dirname(__FILE__), 'rails', 'schema_to_yaml')
6
+ require 'tasks'
7
+ require 'schema_to_rx_yaml'
6
8
 
7
9
  # stores local copy of the application environment ('production', 'test', etc)
8
10
  # so that appropriate values in config/database.yml are used
9
- APP_ENV = defined?(ENV['RAILS_ENV']) ? ENV['RAILS_ENV'] : ENV['MERB_ENV']
11
+ APP_ENV = ENV['RAILS_ENV']
10
12
 
11
13
  namespace :db do
12
14
  namespace :mysql do
@@ -82,9 +84,9 @@ namespace :db do
82
84
 
83
85
  # used to analyze your schema and dump out a model.yml file for converting old rails projects
84
86
  namespace :schema do
85
- desc "Create model.yml from schema.rb"
86
- task :to_yaml => :environment do
87
- SchemaToYaml.schema_to_yaml
87
+ desc "Create RestfulX model.yml from schema.rb"
88
+ task :to_rx_yaml => :environment do
89
+ SchemaToRxYaml.schema_to_rx_yaml
88
90
  end
89
91
  end
90
92
  end
@@ -2,16 +2,15 @@
2
2
  require 'uuidtools'
3
3
 
4
4
  # Extends ActiveRecord models with UUID based IDs
5
- module RestfulX
6
- module UUIDHelper
7
- def self.included(base)
8
- base.class_eval do
9
- before_create :generate_uuid
10
- end
11
- end
12
-
13
- def generate_uuid
14
- self.id = UUIDTools::UUID.random_create.to_s.gsub("-", "") unless self.id
5
+ module RestfulX::UUIDHelper
6
+ def self.included(base)
7
+ base.class_eval do
8
+ before_create :generate_uuid
15
9
  end
16
10
  end
11
+
12
+ # generates new UUID for the record
13
+ def generate_uuid
14
+ self.id = UUIDTools::UUID.random_create.to_s.gsub("-", "") unless self.id
15
+ end
17
16
  end
@@ -0,0 +1,14 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+ require 'amf/class_mapping'
3
+
4
+ # implements ruby-side AMF support for RestfulX
5
+ module RestfulX::AMF
6
+
7
+ ClassMapper = RestfulX::AMF::ClassMapping.new
8
+
9
+ begin
10
+ require RestfulX.amf_serializer == :native ? 'amf/ext' : 'amf/pure'
11
+ rescue LoadError
12
+ require 'amf/pure'
13
+ end
14
+ end
@@ -0,0 +1,106 @@
1
+ module RestfulX::AMF
2
+ class ClassMapping
3
+ class MappingSet
4
+ attr_accessor :default_as_prefix
5
+
6
+ def initialize #:nodoc:
7
+ @as_mappings = {}
8
+ @ruby_mappings = {}
9
+ @default_as_prefix = ""
10
+ end
11
+
12
+ # Map a given AS class to a ruby class.
13
+ #
14
+ # Use fully qualified names for both.
15
+ #
16
+ # Example:
17
+ #
18
+ # m.map :as 'com.example.Date', :ruby => 'Example::Date'
19
+ def map(params)
20
+ [:as, :ruby].each {|k| params[k] = params[k].to_s if params[k] } # Convert params to strings
21
+
22
+ if params.key?(:as) and params.key?(:ruby)
23
+ @as_mappings[params[:as]] = params[:ruby]
24
+ @ruby_mappings[params[:ruby]] = params[:as]
25
+ end
26
+
27
+ if params.key?(:as)
28
+ params[:ruby] = get_ruby_class_name(params[:as])
29
+ end
30
+ end
31
+
32
+ # Returns the AS class name for the given ruby class name, returing nil if
33
+ # not found
34
+ def get_as_class_name(class_name) #:nodoc:
35
+ unless as_class_name = @ruby_mappings[class_name.to_s]
36
+ as_class_name = "#{@default_as_prefix}.#{class_name}"
37
+ @as_mappings[as_class_name] = class_name.to_s
38
+ @ruby_mappings[class_name.to_s] = as_class_name
39
+ end
40
+ as_class_name
41
+ end
42
+
43
+ # Returns the ruby class name for the given AS class name, returing nil if
44
+ # not found
45
+ def get_ruby_class_name(class_name) #:nodoc:
46
+ unless ruby_class_name = @as_mappings[class_name.to_s]
47
+ ruby_class_name = class_name.sub("#{default_as_prefix}.", "")
48
+ @ruby_mappings[ruby_class_name] = class_name.to_s
49
+ @as_mappings[class_name.to_s] = ruby_class_name
50
+ end
51
+ ruby_class_name
52
+ end
53
+ end
54
+
55
+ # Define class mappings in the block. Block is passed a MappingSet object as
56
+ # the first parameter.
57
+ #
58
+ # Example:
59
+ #
60
+ # RestfulX::AMF::ClassMapper.define do |m|
61
+ # m.map :as => 'AsClass', :ruby => 'RubyClass'
62
+ # end
63
+ def define #:yields: mapping_set
64
+ yield mappings
65
+ end
66
+
67
+ # Return default ActionScript prefix to use. This is recommended compared to
68
+ # defining mappings manually
69
+ def default_as_prefix
70
+ mappings.default_as_prefix
71
+ end
72
+
73
+ # Set the default ActionScript prefix (typically a package e.g. com.foobar) to
74
+ # use for all models
75
+ def default_as_prefix=(value)
76
+ mappings.default_as_prefix = value
77
+ end
78
+
79
+ # Returns the AS class name for the given ruby object. Will also take a string
80
+ # containing the ruby class name
81
+ def get_as_class_name(obj)
82
+ # Get class name
83
+ if obj.is_a?(String)
84
+ ruby_class_name = obj
85
+ else
86
+ ruby_class_name = obj.class.name
87
+ end
88
+
89
+ if obj.respond_to?(:unique_id)
90
+ mappings.get_as_class_name(ruby_class_name)
91
+ else
92
+ nil
93
+ end
94
+ end
95
+
96
+ # Return ruby model class name for a given ActionScript model class name
97
+ def get_ruby_class_name(as_class_name)
98
+ mappings.get_ruby_class_name(as_class_name.to_s)
99
+ end
100
+
101
+ private
102
+ def mappings
103
+ @mappings ||= MappingSet.new
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,11 @@
1
+ require 'restfulx/amf/ext/serializer'
2
+
3
+ module RestfulX::AMF #:nodoc:
4
+ # This module holds all the modules/classes that implement AMF's
5
+ # functionality in native C code
6
+ module Ext
7
+ $DEBUG and warn "Using native extension for AMF."
8
+ end
9
+
10
+ include RestfulX::AMF::Ext
11
+ end
Binary file
@@ -0,0 +1,11 @@
1
+ require 'amf/pure/serializer'
2
+
3
+ module RestfulX::AMF #:nodoc:
4
+ # This module holds all the modules/classes that implement AMF's
5
+ # functionality in pure ruby.
6
+ module Pure
7
+ $DEBUG and warn "Using pure library for AMF."
8
+ end
9
+
10
+ include RestfulX::AMF::Pure
11
+ end
@@ -0,0 +1,52 @@
1
+ module RestfulX::AMF::Pure
2
+ module WriteIOHelpers #:nodoc:
3
+ def pack_integer(integer)
4
+ integer = integer & 0x1fffffff
5
+ if(integer < 0x80)
6
+ [integer].pack('c')
7
+ elsif(integer < 0x4000)
8
+ [integer >> 7 & 0x7f | 0x80].pack('c')+
9
+ [integer & 0x7f].pack('c')
10
+ elsif(integer < 0x200000)
11
+ [integer >> 14 & 0x7f | 0x80].pack('c') +
12
+ [integer >> 7 & 0x7f | 0x80].pack('c') +
13
+ [integer & 0x7f].pack('c')
14
+ else
15
+ [integer >> 22 & 0x7f | 0x80].pack('c')+
16
+ [integer >> 15 & 0x7f | 0x80].pack('c')+
17
+ [integer >> 8 & 0x7f | 0x80].pack('c')+
18
+ [integer & 0xff].pack('c')
19
+ end
20
+ end
21
+
22
+ def pack_double(double)
23
+ [double].pack('G')
24
+ end
25
+
26
+ def pack_int8(val)
27
+ [val].pack('c')
28
+ end
29
+
30
+ def pack_int16_network(val)
31
+ [val].pack('n')
32
+ end
33
+
34
+ def pack_word32_network(val)
35
+ str = [val].pack('L')
36
+ str.reverse! if byte_order_little? # swap bytes as native=little (and we want network)
37
+ str
38
+ end
39
+
40
+ def byte_order
41
+ if [0x12345678].pack("L") == "\x12\x34\x56\x78"
42
+ :BigEndian
43
+ else
44
+ :LittleEndian
45
+ end
46
+ end
47
+
48
+ def byte_order_little?
49
+ (byte_order == :LittleEndian) ? true : false;
50
+ end
51
+ end
52
+ end