activerecord_authorails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +3043 -0
- data/README +360 -0
- data/RUNNING_UNIT_TESTS +64 -0
- data/Rakefile +226 -0
- data/examples/associations.png +0 -0
- data/examples/associations.rb +87 -0
- data/examples/shared_setup.rb +15 -0
- data/examples/validation.rb +85 -0
- data/install.rb +30 -0
- data/lib/active_record.rb +85 -0
- data/lib/active_record/acts/list.rb +244 -0
- data/lib/active_record/acts/nested_set.rb +211 -0
- data/lib/active_record/acts/tree.rb +89 -0
- data/lib/active_record/aggregations.rb +191 -0
- data/lib/active_record/associations.rb +1637 -0
- data/lib/active_record/associations/association_collection.rb +190 -0
- data/lib/active_record/associations/association_proxy.rb +158 -0
- data/lib/active_record/associations/belongs_to_association.rb +56 -0
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +169 -0
- data/lib/active_record/associations/has_many_association.rb +210 -0
- data/lib/active_record/associations/has_many_through_association.rb +247 -0
- data/lib/active_record/associations/has_one_association.rb +80 -0
- data/lib/active_record/attribute_methods.rb +75 -0
- data/lib/active_record/base.rb +2164 -0
- data/lib/active_record/calculations.rb +270 -0
- data/lib/active_record/callbacks.rb +367 -0
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +279 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +130 -0
- data/lib/active_record/connection_adapters/abstract/quoting.rb +58 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +343 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +310 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +161 -0
- data/lib/active_record/connection_adapters/db2_adapter.rb +228 -0
- data/lib/active_record/connection_adapters/firebird_adapter.rb +728 -0
- data/lib/active_record/connection_adapters/frontbase_adapter.rb +861 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +414 -0
- data/lib/active_record/connection_adapters/openbase_adapter.rb +350 -0
- data/lib/active_record/connection_adapters/oracle_adapter.rb +689 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +584 -0
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +407 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +591 -0
- data/lib/active_record/connection_adapters/sybase_adapter.rb +662 -0
- data/lib/active_record/deprecated_associations.rb +104 -0
- data/lib/active_record/deprecated_finders.rb +44 -0
- data/lib/active_record/fixtures.rb +628 -0
- data/lib/active_record/locking/optimistic.rb +106 -0
- data/lib/active_record/locking/pessimistic.rb +77 -0
- data/lib/active_record/migration.rb +394 -0
- data/lib/active_record/observer.rb +178 -0
- data/lib/active_record/query_cache.rb +64 -0
- data/lib/active_record/reflection.rb +222 -0
- data/lib/active_record/schema.rb +58 -0
- data/lib/active_record/schema_dumper.rb +149 -0
- data/lib/active_record/timestamp.rb +51 -0
- data/lib/active_record/transactions.rb +136 -0
- data/lib/active_record/validations.rb +843 -0
- data/lib/active_record/vendor/db2.rb +362 -0
- data/lib/active_record/vendor/mysql.rb +1214 -0
- data/lib/active_record/vendor/simple.rb +693 -0
- data/lib/active_record/version.rb +9 -0
- data/lib/active_record/wrappers/yaml_wrapper.rb +15 -0
- data/lib/active_record/wrappings.rb +58 -0
- data/lib/active_record/xml_serialization.rb +308 -0
- data/test/aaa_create_tables_test.rb +59 -0
- data/test/abstract_unit.rb +77 -0
- data/test/active_schema_test_mysql.rb +31 -0
- data/test/adapter_test.rb +87 -0
- data/test/adapter_test_sqlserver.rb +81 -0
- data/test/aggregations_test.rb +95 -0
- data/test/all.sh +8 -0
- data/test/ar_schema_test.rb +33 -0
- data/test/association_inheritance_reload.rb +14 -0
- data/test/associations/callbacks_test.rb +126 -0
- data/test/associations/cascaded_eager_loading_test.rb +138 -0
- data/test/associations/eager_test.rb +393 -0
- data/test/associations/extension_test.rb +42 -0
- data/test/associations/join_model_test.rb +497 -0
- data/test/associations_test.rb +1809 -0
- data/test/attribute_methods_test.rb +49 -0
- data/test/base_test.rb +1586 -0
- data/test/binary_test.rb +37 -0
- data/test/calculations_test.rb +219 -0
- data/test/callbacks_test.rb +377 -0
- data/test/class_inheritable_attributes_test.rb +32 -0
- data/test/column_alias_test.rb +17 -0
- data/test/connection_test_firebird.rb +8 -0
- data/test/connections/native_db2/connection.rb +25 -0
- data/test/connections/native_firebird/connection.rb +26 -0
- data/test/connections/native_frontbase/connection.rb +27 -0
- data/test/connections/native_mysql/connection.rb +24 -0
- data/test/connections/native_openbase/connection.rb +21 -0
- data/test/connections/native_oracle/connection.rb +27 -0
- data/test/connections/native_postgresql/connection.rb +23 -0
- data/test/connections/native_sqlite/connection.rb +34 -0
- data/test/connections/native_sqlite3/connection.rb +34 -0
- data/test/connections/native_sqlite3/in_memory_connection.rb +18 -0
- data/test/connections/native_sqlserver/connection.rb +23 -0
- data/test/connections/native_sqlserver_odbc/connection.rb +25 -0
- data/test/connections/native_sybase/connection.rb +23 -0
- data/test/copy_table_sqlite.rb +64 -0
- data/test/datatype_test_postgresql.rb +52 -0
- data/test/default_test_firebird.rb +16 -0
- data/test/defaults_test.rb +60 -0
- data/test/deprecated_associations_test.rb +396 -0
- data/test/deprecated_finder_test.rb +151 -0
- data/test/empty_date_time_test.rb +25 -0
- data/test/finder_test.rb +504 -0
- data/test/fixtures/accounts.yml +28 -0
- data/test/fixtures/author.rb +99 -0
- data/test/fixtures/author_favorites.yml +4 -0
- data/test/fixtures/authors.yml +7 -0
- data/test/fixtures/auto_id.rb +4 -0
- data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +1 -0
- data/test/fixtures/bad_fixtures/attr_with_spaces +1 -0
- data/test/fixtures/bad_fixtures/blank_line +3 -0
- data/test/fixtures/bad_fixtures/duplicate_attributes +3 -0
- data/test/fixtures/bad_fixtures/missing_value +1 -0
- data/test/fixtures/binary.rb +2 -0
- data/test/fixtures/categories.yml +14 -0
- data/test/fixtures/categories/special_categories.yml +9 -0
- data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
- data/test/fixtures/categories_ordered.yml +7 -0
- data/test/fixtures/categories_posts.yml +23 -0
- data/test/fixtures/categorization.rb +5 -0
- data/test/fixtures/categorizations.yml +17 -0
- data/test/fixtures/category.rb +20 -0
- data/test/fixtures/column_name.rb +3 -0
- data/test/fixtures/comment.rb +23 -0
- data/test/fixtures/comments.yml +59 -0
- data/test/fixtures/companies.yml +55 -0
- data/test/fixtures/company.rb +107 -0
- data/test/fixtures/company_in_module.rb +59 -0
- data/test/fixtures/computer.rb +3 -0
- data/test/fixtures/computers.yml +4 -0
- data/test/fixtures/course.rb +3 -0
- data/test/fixtures/courses.yml +7 -0
- data/test/fixtures/customer.rb +55 -0
- data/test/fixtures/customers.yml +17 -0
- data/test/fixtures/db_definitions/db2.drop.sql +32 -0
- data/test/fixtures/db_definitions/db2.sql +231 -0
- data/test/fixtures/db_definitions/db22.drop.sql +2 -0
- data/test/fixtures/db_definitions/db22.sql +5 -0
- data/test/fixtures/db_definitions/firebird.drop.sql +63 -0
- data/test/fixtures/db_definitions/firebird.sql +304 -0
- data/test/fixtures/db_definitions/firebird2.drop.sql +2 -0
- data/test/fixtures/db_definitions/firebird2.sql +6 -0
- data/test/fixtures/db_definitions/frontbase.drop.sql +32 -0
- data/test/fixtures/db_definitions/frontbase.sql +268 -0
- data/test/fixtures/db_definitions/frontbase2.drop.sql +1 -0
- data/test/fixtures/db_definitions/frontbase2.sql +4 -0
- data/test/fixtures/db_definitions/mysql.drop.sql +32 -0
- data/test/fixtures/db_definitions/mysql.sql +234 -0
- data/test/fixtures/db_definitions/mysql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/mysql2.sql +5 -0
- data/test/fixtures/db_definitions/openbase.drop.sql +2 -0
- data/test/fixtures/db_definitions/openbase.sql +302 -0
- data/test/fixtures/db_definitions/openbase2.drop.sql +2 -0
- data/test/fixtures/db_definitions/openbase2.sql +7 -0
- data/test/fixtures/db_definitions/oracle.drop.sql +65 -0
- data/test/fixtures/db_definitions/oracle.sql +325 -0
- data/test/fixtures/db_definitions/oracle2.drop.sql +2 -0
- data/test/fixtures/db_definitions/oracle2.sql +6 -0
- data/test/fixtures/db_definitions/postgresql.drop.sql +37 -0
- data/test/fixtures/db_definitions/postgresql.sql +263 -0
- data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
- data/test/fixtures/db_definitions/postgresql2.sql +5 -0
- data/test/fixtures/db_definitions/schema.rb +60 -0
- data/test/fixtures/db_definitions/sqlite.drop.sql +32 -0
- data/test/fixtures/db_definitions/sqlite.sql +215 -0
- data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlite2.sql +5 -0
- data/test/fixtures/db_definitions/sqlserver.drop.sql +34 -0
- data/test/fixtures/db_definitions/sqlserver.sql +243 -0
- data/test/fixtures/db_definitions/sqlserver2.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlserver2.sql +5 -0
- data/test/fixtures/db_definitions/sybase.drop.sql +34 -0
- data/test/fixtures/db_definitions/sybase.sql +218 -0
- data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
- data/test/fixtures/db_definitions/sybase2.sql +5 -0
- data/test/fixtures/default.rb +2 -0
- data/test/fixtures/developer.rb +52 -0
- data/test/fixtures/developers.yml +21 -0
- data/test/fixtures/developers_projects.yml +17 -0
- data/test/fixtures/developers_projects/david_action_controller +3 -0
- data/test/fixtures/developers_projects/david_active_record +3 -0
- data/test/fixtures/developers_projects/jamis_active_record +2 -0
- data/test/fixtures/edge.rb +5 -0
- data/test/fixtures/edges.yml +6 -0
- data/test/fixtures/entrant.rb +3 -0
- data/test/fixtures/entrants.yml +14 -0
- data/test/fixtures/fk_test_has_fk.yml +3 -0
- data/test/fixtures/fk_test_has_pk.yml +2 -0
- data/test/fixtures/flowers.jpg +0 -0
- data/test/fixtures/funny_jokes.yml +10 -0
- data/test/fixtures/joke.rb +6 -0
- data/test/fixtures/keyboard.rb +3 -0
- data/test/fixtures/legacy_thing.rb +3 -0
- data/test/fixtures/legacy_things.yml +3 -0
- data/test/fixtures/migrations/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations/2_we_need_reminders.rb +12 -0
- data/test/fixtures/migrations/3_innocent_jointable.rb +12 -0
- data/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb +15 -0
- data/test/fixtures/migrations_with_duplicate/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations_with_duplicate/2_we_need_reminders.rb +12 -0
- data/test/fixtures/migrations_with_duplicate/3_foo.rb +7 -0
- data/test/fixtures/migrations_with_duplicate/3_innocent_jointable.rb +12 -0
- data/test/fixtures/migrations_with_missing_versions/1000_people_have_middle_names.rb +9 -0
- data/test/fixtures/migrations_with_missing_versions/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations_with_missing_versions/3_we_need_reminders.rb +12 -0
- data/test/fixtures/migrations_with_missing_versions/4_innocent_jointable.rb +12 -0
- data/test/fixtures/mixed_case_monkey.rb +3 -0
- data/test/fixtures/mixed_case_monkeys.yml +6 -0
- data/test/fixtures/mixin.rb +63 -0
- data/test/fixtures/mixins.yml +127 -0
- data/test/fixtures/movie.rb +5 -0
- data/test/fixtures/movies.yml +7 -0
- data/test/fixtures/naked/csv/accounts.csv +1 -0
- data/test/fixtures/naked/yml/accounts.yml +1 -0
- data/test/fixtures/naked/yml/companies.yml +1 -0
- data/test/fixtures/naked/yml/courses.yml +1 -0
- data/test/fixtures/order.rb +4 -0
- data/test/fixtures/people.yml +3 -0
- data/test/fixtures/person.rb +4 -0
- data/test/fixtures/post.rb +58 -0
- data/test/fixtures/posts.yml +48 -0
- data/test/fixtures/project.rb +27 -0
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/reader.rb +4 -0
- data/test/fixtures/readers.yml +4 -0
- data/test/fixtures/reply.rb +37 -0
- data/test/fixtures/subject.rb +4 -0
- data/test/fixtures/subscriber.rb +6 -0
- data/test/fixtures/subscribers/first +2 -0
- data/test/fixtures/subscribers/second +2 -0
- data/test/fixtures/tag.rb +7 -0
- data/test/fixtures/tagging.rb +6 -0
- data/test/fixtures/taggings.yml +18 -0
- data/test/fixtures/tags.yml +7 -0
- data/test/fixtures/task.rb +3 -0
- data/test/fixtures/tasks.yml +7 -0
- data/test/fixtures/topic.rb +25 -0
- data/test/fixtures/topics.yml +22 -0
- data/test/fixtures/vertex.rb +9 -0
- data/test/fixtures/vertices.yml +4 -0
- data/test/fixtures_test.rb +401 -0
- data/test/inheritance_test.rb +205 -0
- data/test/lifecycle_test.rb +137 -0
- data/test/locking_test.rb +190 -0
- data/test/method_scoping_test.rb +416 -0
- data/test/migration_test.rb +768 -0
- data/test/migration_test_firebird.rb +124 -0
- data/test/mixin_nested_set_test.rb +196 -0
- data/test/mixin_test.rb +550 -0
- data/test/modules_test.rb +34 -0
- data/test/multiple_db_test.rb +60 -0
- data/test/pk_test.rb +104 -0
- data/test/readonly_test.rb +107 -0
- data/test/reflection_test.rb +159 -0
- data/test/schema_authorization_test_postgresql.rb +75 -0
- data/test/schema_dumper_test.rb +96 -0
- data/test/schema_test_postgresql.rb +64 -0
- data/test/synonym_test_oracle.rb +17 -0
- data/test/table_name_test_sqlserver.rb +23 -0
- data/test/threaded_connections_test.rb +48 -0
- data/test/transactions_test.rb +230 -0
- data/test/unconnected_test.rb +32 -0
- data/test/validations_test.rb +1097 -0
- data/test/xml_serialization_test.rb +125 -0
- metadata +365 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Wrappings #:nodoc:
|
5
|
+
class YamlWrapper < AbstractWrapper #:nodoc:
|
6
|
+
def wrap(attribute) attribute.to_yaml end
|
7
|
+
def unwrap(attribute) YAML::load(attribute) end
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods #:nodoc:
|
11
|
+
# Wraps the attribute in Yaml encoding
|
12
|
+
def wrap_in_yaml(*attributes) wrap_with(YamlWrapper, attributes) end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
# A plugin framework for wrapping attribute values before they go in and unwrapping them after they go out of the database.
|
3
|
+
# This was intended primarily for YAML wrapping of arrays and hashes, but this behavior is now native in the Base class.
|
4
|
+
# So for now this framework is laying dormant until a need pops up.
|
5
|
+
module Wrappings #:nodoc:
|
6
|
+
module ClassMethods #:nodoc:
|
7
|
+
def wrap_with(wrapper, *attributes)
|
8
|
+
[ attributes ].flat.each { |attribute| wrapper.wrap(attribute) }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.extend(ClassMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
class AbstractWrapper #:nodoc:
|
17
|
+
def self.wrap(attribute, record_binding) #:nodoc:
|
18
|
+
%w( before_save after_save after_initialize ).each do |callback|
|
19
|
+
eval "#{callback} #{name}.new('#{attribute}')", record_binding
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(attribute) #:nodoc:
|
24
|
+
@attribute = attribute
|
25
|
+
end
|
26
|
+
|
27
|
+
def save_wrapped_attribute(record) #:nodoc:
|
28
|
+
if record.attribute_present?(@attribute)
|
29
|
+
record.send(
|
30
|
+
"write_attribute",
|
31
|
+
@attribute,
|
32
|
+
wrap(record.send("read_attribute", @attribute))
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def load_wrapped_attribute(record) #:nodoc:
|
38
|
+
if record.attribute_present?(@attribute)
|
39
|
+
record.send(
|
40
|
+
"write_attribute",
|
41
|
+
@attribute,
|
42
|
+
unwrap(record.send("read_attribute", @attribute))
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
alias_method :before_save, :save_wrapped_attribute #:nodoc:
|
48
|
+
alias_method :after_save, :load_wrapped_attribute #:nodoc:
|
49
|
+
alias_method :after_initialize, :after_save #:nodoc:
|
50
|
+
|
51
|
+
# Overwrite to implement the logic that'll take the regular attribute and wrap it.
|
52
|
+
def wrap(attribute) end
|
53
|
+
|
54
|
+
# Overwrite to implement the logic that'll take the wrapped attribute and unwrap it.
|
55
|
+
def unwrap(attribute) end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,308 @@
|
|
1
|
+
module ActiveRecord #:nodoc:
|
2
|
+
module XmlSerialization
|
3
|
+
# Builds an XML document to represent the model. Some configuration is
|
4
|
+
# availble through +options+, however more complicated cases should use
|
5
|
+
# override ActiveRecord's to_xml.
|
6
|
+
#
|
7
|
+
# By default the generated XML document will include the processing
|
8
|
+
# instruction and all object's attributes. For example:
|
9
|
+
#
|
10
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
11
|
+
# <topic>
|
12
|
+
# <title>The First Topic</title>
|
13
|
+
# <author-name>David</author-name>
|
14
|
+
# <id type="integer">1</id>
|
15
|
+
# <approved type="boolean">false</approved>
|
16
|
+
# <replies-count type="integer">0</replies-count>
|
17
|
+
# <bonus-time type="datetime">2000-01-01T08:28:00+12:00</bonus-time>
|
18
|
+
# <written-on type="datetime">2003-07-16T09:28:00+1200</written-on>
|
19
|
+
# <content>Have a nice day</content>
|
20
|
+
# <author-email-address>david@loudthinking.com</author-email-address>
|
21
|
+
# <parent-id></parent-id>
|
22
|
+
# <last-read type="date">2004-04-15</last-read>
|
23
|
+
# </topic>
|
24
|
+
#
|
25
|
+
# This behavior can be controlled with :only, :except,
|
26
|
+
# :skip_instruct, :skip_types and :dasherize. The :only and
|
27
|
+
# :except options are the same as for the #attributes method.
|
28
|
+
# The default is to dasherize all column names, to disable this,
|
29
|
+
# set :dasherize to false. To not have the column type included
|
30
|
+
# in the XML output, set :skip_types to false.
|
31
|
+
#
|
32
|
+
# For instance:
|
33
|
+
#
|
34
|
+
# topic.to_xml(:skip_instruct => true, :except => [ :id, :bonus_time, :written_on, :replies_count ])
|
35
|
+
#
|
36
|
+
# <topic>
|
37
|
+
# <title>The First Topic</title>
|
38
|
+
# <author-name>David</author-name>
|
39
|
+
# <approved type="boolean">false</approved>
|
40
|
+
# <content>Have a nice day</content>
|
41
|
+
# <author-email-address>david@loudthinking.com</author-email-address>
|
42
|
+
# <parent-id></parent-id>
|
43
|
+
# <last-read type="date">2004-04-15</last-read>
|
44
|
+
# </topic>
|
45
|
+
#
|
46
|
+
# To include first level associations use :include
|
47
|
+
#
|
48
|
+
# firm.to_xml :include => [ :account, :clients ]
|
49
|
+
#
|
50
|
+
# <?xml version="1.0" encoding="UTF-8"?>
|
51
|
+
# <firm>
|
52
|
+
# <id type="integer">1</id>
|
53
|
+
# <rating type="integer">1</rating>
|
54
|
+
# <name>37signals</name>
|
55
|
+
# <clients>
|
56
|
+
# <client>
|
57
|
+
# <rating type="integer">1</rating>
|
58
|
+
# <name>Summit</name>
|
59
|
+
# </client>
|
60
|
+
# <client>
|
61
|
+
# <rating type="integer">1</rating>
|
62
|
+
# <name>Microsoft</name>
|
63
|
+
# </client>
|
64
|
+
# </clients>
|
65
|
+
# <account>
|
66
|
+
# <id type="integer">1</id>
|
67
|
+
# <credit-limit type="integer">50</credit-limit>
|
68
|
+
# </account>
|
69
|
+
# </firm>
|
70
|
+
#
|
71
|
+
# To include any methods on the object(s) being called use :methods
|
72
|
+
#
|
73
|
+
# firm.to_xml :methods => [ :calculated_earnings, :real_earnings ]
|
74
|
+
#
|
75
|
+
# <firm>
|
76
|
+
# # ... normal attributes as shown above ...
|
77
|
+
# <calculated-earnings>100000000000000000</calculated-earnings>
|
78
|
+
# <real-earnings>5</real-earnings>
|
79
|
+
# </firm>
|
80
|
+
#
|
81
|
+
# To call any Proc's on the object(s) use :procs. The Proc's
|
82
|
+
# are passed a modified version of the options hash that was
|
83
|
+
# given to #to_xml.
|
84
|
+
#
|
85
|
+
# proc = Proc.new { |options| options[:builder].tag!('abc', 'def') }
|
86
|
+
# firm.to_xml :procs => [ proc ]
|
87
|
+
#
|
88
|
+
# <firm>
|
89
|
+
# # ... normal attributes as shown above ...
|
90
|
+
# <abc>def</abc>
|
91
|
+
# </firm>
|
92
|
+
#
|
93
|
+
# You may override the to_xml method in your ActiveRecord::Base
|
94
|
+
# subclasses if you need to. The general form of doing this is
|
95
|
+
#
|
96
|
+
# class IHaveMyOwnXML < ActiveRecord::Base
|
97
|
+
# def to_xml(options = {})
|
98
|
+
# options[:indent] ||= 2
|
99
|
+
# xml = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
|
100
|
+
# xml.instruct! unless options[:skip_instruct]
|
101
|
+
# xml.level_one do
|
102
|
+
# xml.tag!(:second_level, 'content')
|
103
|
+
# end
|
104
|
+
# end
|
105
|
+
# end
|
106
|
+
def to_xml(options = {})
|
107
|
+
XmlSerializer.new(self, options).to_s
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class XmlSerializer #:nodoc:
|
112
|
+
attr_reader :options
|
113
|
+
|
114
|
+
def initialize(record, options = {})
|
115
|
+
@record, @options = record, options.dup
|
116
|
+
end
|
117
|
+
|
118
|
+
def builder
|
119
|
+
@builder ||= begin
|
120
|
+
options[:indent] ||= 2
|
121
|
+
builder = options[:builder] ||= Builder::XmlMarkup.new(:indent => options[:indent])
|
122
|
+
|
123
|
+
unless options[:skip_instruct]
|
124
|
+
builder.instruct!
|
125
|
+
options[:skip_instruct] = true
|
126
|
+
end
|
127
|
+
|
128
|
+
builder
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def root
|
133
|
+
root = (options[:root] || @record.class.to_s.underscore).to_s
|
134
|
+
dasherize? ? root.dasherize : root
|
135
|
+
end
|
136
|
+
|
137
|
+
def dasherize?
|
138
|
+
!options.has_key?(:dasherize) || options[:dasherize]
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
# To replicate the behavior in ActiveRecord#attributes,
|
143
|
+
# :except takes precedence over :only. If :only is not set
|
144
|
+
# for a N level model but is set for the N+1 level models,
|
145
|
+
# then because :except is set to a default value, the second
|
146
|
+
# level model can have both :except and :only set. So if
|
147
|
+
# :only is set, always delete :except.
|
148
|
+
def serializable_attributes
|
149
|
+
attribute_names = @record.attribute_names
|
150
|
+
|
151
|
+
if options[:only]
|
152
|
+
options.delete(:except)
|
153
|
+
attribute_names = attribute_names & Array(options[:only]).collect { |n| n.to_s }
|
154
|
+
else
|
155
|
+
options[:except] = Array(options[:except]) | Array(@record.class.inheritance_column)
|
156
|
+
attribute_names = attribute_names - options[:except].collect { |n| n.to_s }
|
157
|
+
end
|
158
|
+
|
159
|
+
attribute_names.collect { |name| Attribute.new(name, @record) }
|
160
|
+
end
|
161
|
+
|
162
|
+
def serializable_method_attributes
|
163
|
+
Array(options[:methods]).collect { |name| MethodAttribute.new(name.to_s, @record) }
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
def add_attributes
|
168
|
+
(serializable_attributes + serializable_method_attributes).each do |attribute|
|
169
|
+
add_tag(attribute)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def add_includes
|
174
|
+
if include_associations = options.delete(:include)
|
175
|
+
root_only_or_except = { :except => options[:except],
|
176
|
+
:only => options[:only] }
|
177
|
+
|
178
|
+
include_has_options = include_associations.is_a?(Hash)
|
179
|
+
|
180
|
+
for association in include_has_options ? include_associations.keys : Array(include_associations)
|
181
|
+
association_options = include_has_options ? include_associations[association] : root_only_or_except
|
182
|
+
|
183
|
+
opts = options.merge(association_options)
|
184
|
+
|
185
|
+
case @record.class.reflect_on_association(association).macro
|
186
|
+
when :has_many, :has_and_belongs_to_many
|
187
|
+
records = @record.send(association).to_a
|
188
|
+
unless records.empty?
|
189
|
+
tag = records.first.class.to_s.underscore.pluralize
|
190
|
+
tag = tag.dasherize if dasherize?
|
191
|
+
|
192
|
+
builder.tag!(tag) do
|
193
|
+
records.each { |r| r.to_xml(opts.merge(:root => association.to_s.singularize)) }
|
194
|
+
end
|
195
|
+
end
|
196
|
+
when :has_one, :belongs_to
|
197
|
+
if record = @record.send(association)
|
198
|
+
record.to_xml(opts.merge(:root => association))
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
options[:include] = include_associations
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
def add_procs
|
208
|
+
if procs = options.delete(:procs)
|
209
|
+
[ *procs ].each do |proc|
|
210
|
+
proc.call(options)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
def add_tag(attribute)
|
217
|
+
builder.tag!(
|
218
|
+
dasherize? ? attribute.name.dasherize : attribute.name,
|
219
|
+
attribute.value.to_s,
|
220
|
+
attribute.decorations(!options[:skip_types])
|
221
|
+
)
|
222
|
+
end
|
223
|
+
|
224
|
+
def serialize
|
225
|
+
args = [root]
|
226
|
+
if options[:namespace]
|
227
|
+
args << {:xmlns=>options[:namespace]}
|
228
|
+
end
|
229
|
+
|
230
|
+
builder.tag!(*args) do
|
231
|
+
add_attributes
|
232
|
+
add_includes
|
233
|
+
add_procs
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
alias_method :to_s, :serialize
|
238
|
+
|
239
|
+
class Attribute #:nodoc:
|
240
|
+
attr_reader :name, :value, :type
|
241
|
+
|
242
|
+
def initialize(name, record)
|
243
|
+
@name, @record = name, record
|
244
|
+
|
245
|
+
@type = compute_type
|
246
|
+
@value = compute_value
|
247
|
+
end
|
248
|
+
|
249
|
+
# There is a significant speed improvement if the value
|
250
|
+
# does not need to be escaped, as #tag! escapes all values
|
251
|
+
# to ensure that valid XML is generated. For known binary
|
252
|
+
# values, it is at least an order of magnitude faster to
|
253
|
+
# Base64 encode binary values and directly put them in the
|
254
|
+
# output XML than to pass the original value or the Base64
|
255
|
+
# encoded value to the #tag! method. It definitely makes
|
256
|
+
# no sense to Base64 encode the value and then give it to
|
257
|
+
# #tag!, since that just adds additional overhead.
|
258
|
+
def needs_encoding?
|
259
|
+
![ :binary, :date, :datetime, :boolean, :float, :integer ].include?(type)
|
260
|
+
end
|
261
|
+
|
262
|
+
def decorations(include_types = true)
|
263
|
+
decorations = {}
|
264
|
+
|
265
|
+
if type == :binary
|
266
|
+
decorations[:encoding] = 'base64'
|
267
|
+
end
|
268
|
+
|
269
|
+
if include_types && type != :string
|
270
|
+
decorations[:type] = type
|
271
|
+
end
|
272
|
+
|
273
|
+
decorations
|
274
|
+
end
|
275
|
+
|
276
|
+
protected
|
277
|
+
def compute_type
|
278
|
+
type = @record.class.columns_hash[name].type
|
279
|
+
|
280
|
+
case type
|
281
|
+
when :text
|
282
|
+
:string
|
283
|
+
when :time
|
284
|
+
:datetime
|
285
|
+
else
|
286
|
+
type
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
def compute_value
|
291
|
+
value = @record.send(name)
|
292
|
+
|
293
|
+
if formatter = Hash::XML_FORMATTING[type.to_s]
|
294
|
+
value ? formatter.call(value) : nil
|
295
|
+
else
|
296
|
+
value
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
class MethodAttribute < Attribute #:nodoc:
|
302
|
+
protected
|
303
|
+
def compute_type
|
304
|
+
Hash::XML_TYPE_NAMES[@record.send(name).class.name] || :string
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# The filename begins with "aaa" to ensure this is the first test.
|
2
|
+
require 'abstract_unit'
|
3
|
+
|
4
|
+
class AAACreateTablesTest < Test::Unit::TestCase
|
5
|
+
self.use_transactional_fixtures = false
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@base_path = "#{File.dirname(__FILE__)}/fixtures/db_definitions"
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_drop_and_create_main_tables
|
12
|
+
recreate ActiveRecord::Base
|
13
|
+
assert true
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_load_schema
|
17
|
+
if ActiveRecord::Base.connection.supports_migrations?
|
18
|
+
eval(File.read("#{File.dirname(__FILE__)}/fixtures/db_definitions/schema.rb"))
|
19
|
+
else
|
20
|
+
recreate ActiveRecord::Base, '3'
|
21
|
+
end
|
22
|
+
assert true
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_drop_and_create_courses_table
|
26
|
+
recreate Course, '2'
|
27
|
+
assert true
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def recreate(base, suffix = nil)
|
32
|
+
connection = base.connection
|
33
|
+
adapter_name = connection.adapter_name.downcase + suffix.to_s
|
34
|
+
execute_sql_file "#{@base_path}/#{adapter_name}.drop.sql", connection
|
35
|
+
execute_sql_file "#{@base_path}/#{adapter_name}.sql", connection
|
36
|
+
end
|
37
|
+
|
38
|
+
def execute_sql_file(path, connection)
|
39
|
+
# OpenBase has a different format for sql files
|
40
|
+
if current_adapter?(:OpenBaseAdapter) then
|
41
|
+
File.read(path).split("go").each_with_index do |sql, i|
|
42
|
+
begin
|
43
|
+
# OpenBase does not support comments embedded in sql
|
44
|
+
connection.execute(sql,"SQL statement ##{i}") unless sql.blank?
|
45
|
+
rescue ActiveRecord::StatementInvalid
|
46
|
+
#$stderr.puts "warning: #{$!}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
else
|
50
|
+
File.read(path).split(';').each_with_index do |sql, i|
|
51
|
+
begin
|
52
|
+
connection.execute("\n\n-- statement ##{i}\n#{sql}\n") unless sql.blank?
|
53
|
+
rescue ActiveRecord::StatementInvalid
|
54
|
+
#$stderr.puts "warning: #{$!}"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|