caruby-core 1.4.2 → 1.4.3

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/History.txt +10 -0
  2. data/lib/caruby/cli/command.rb +10 -8
  3. data/lib/caruby/database/fetched_matcher.rb +28 -39
  4. data/lib/caruby/database/lazy_loader.rb +101 -0
  5. data/lib/caruby/database/persistable.rb +190 -167
  6. data/lib/caruby/database/persistence_service.rb +21 -7
  7. data/lib/caruby/database/persistifier.rb +185 -0
  8. data/lib/caruby/database/reader.rb +106 -176
  9. data/lib/caruby/database/saved_matcher.rb +56 -0
  10. data/lib/caruby/database/search_template_builder.rb +1 -1
  11. data/lib/caruby/database/sql_executor.rb +8 -7
  12. data/lib/caruby/database/store_template_builder.rb +134 -61
  13. data/lib/caruby/database/writer.rb +252 -52
  14. data/lib/caruby/database.rb +88 -67
  15. data/lib/caruby/domain/attribute_initializer.rb +16 -0
  16. data/lib/caruby/domain/attribute_metadata.rb +161 -72
  17. data/lib/caruby/domain/id_alias.rb +22 -0
  18. data/lib/caruby/domain/inversible.rb +91 -0
  19. data/lib/caruby/domain/merge.rb +116 -35
  20. data/lib/caruby/domain/properties.rb +1 -1
  21. data/lib/caruby/domain/reference_visitor.rb +207 -71
  22. data/lib/caruby/domain/resource_attributes.rb +93 -80
  23. data/lib/caruby/domain/resource_dependency.rb +22 -97
  24. data/lib/caruby/domain/resource_introspection.rb +21 -28
  25. data/lib/caruby/domain/resource_inverse.rb +134 -0
  26. data/lib/caruby/domain/resource_metadata.rb +41 -19
  27. data/lib/caruby/domain/resource_module.rb +42 -33
  28. data/lib/caruby/import/java.rb +8 -9
  29. data/lib/caruby/migration/migrator.rb +20 -7
  30. data/lib/caruby/migration/resource_module.rb +0 -2
  31. data/lib/caruby/resource.rb +132 -351
  32. data/lib/caruby/util/cache.rb +4 -1
  33. data/lib/caruby/util/class.rb +48 -1
  34. data/lib/caruby/util/collection.rb +54 -18
  35. data/lib/caruby/util/inflector.rb +7 -0
  36. data/lib/caruby/util/options.rb +35 -31
  37. data/lib/caruby/util/partial_order.rb +1 -1
  38. data/lib/caruby/util/properties.rb +2 -2
  39. data/lib/caruby/util/stopwatch.rb +16 -8
  40. data/lib/caruby/util/transitive_closure.rb +1 -1
  41. data/lib/caruby/util/visitor.rb +342 -328
  42. data/lib/caruby/version.rb +1 -1
  43. data/lib/caruby/yard/resource_metadata_handler.rb +8 -0
  44. data/lib/caruby.rb +2 -0
  45. metadata +10 -9
  46. data/lib/caruby/database/saved_merger.rb +0 -131
  47. data/lib/caruby/domain/annotatable.rb +0 -25
  48. data/lib/caruby/domain/annotation.rb +0 -23
  49. data/lib/caruby/import/annotatable_class.rb +0 -28
  50. data/lib/caruby/import/annotation_class.rb +0 -27
  51. data/lib/caruby/import/annotation_module.rb +0 -67
  52. data/lib/caruby/migration/resource.rb +0 -8
@@ -1,3 +1,3 @@
1
1
  module CaRuby
2
- VERSION = "1.4.2"
2
+ VERSION = "1.4.3"
3
3
  end
@@ -0,0 +1,8 @@
1
+ class ResourceMetadataHandler < YARD::Handlers::Ruby::Legacy::AttributeHandler
2
+ handles method_call(/\Aqualify_attribute\b/)
3
+ namespace_only
4
+
5
+ def process
6
+ push_state(:scope => :class) { super }
7
+ end
8
+ end
data/lib/caruby.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'caruby/resource'
2
+
1
3
  # CaRuby is a JRuby facade for the caBIG application APIs.
2
4
  # See the [http://http://caruby.rubyforge.org/](caRuby) home page for more information.
3
5
  module CaRuby;end
metadata CHANGED
@@ -6,11 +6,11 @@ executables: []
6
6
 
7
7
  version: !ruby/object:Gem::Version
8
8
  prerelease: false
9
- version: 1.4.2
9
+ version: 1.4.3
10
10
  segments:
11
11
  - 1
12
12
  - 4
13
- - 2
13
+ - 3
14
14
  post_install_message:
15
15
  date: 2010-11-30 08:00:00 +00:00
16
16
  files:
@@ -28,17 +28,20 @@ files:
28
28
  - lib/caruby/csv/csv_mapper.rb
29
29
  - lib/caruby/csv/csvio.rb
30
30
  - lib/caruby/database/fetched_matcher.rb
31
+ - lib/caruby/database/lazy_loader.rb
31
32
  - lib/caruby/database/persistable.rb
32
33
  - lib/caruby/database/persistence_service.rb
34
+ - lib/caruby/database/persistifier.rb
33
35
  - lib/caruby/database/reader.rb
34
- - lib/caruby/database/saved_merger.rb
36
+ - lib/caruby/database/saved_matcher.rb
35
37
  - lib/caruby/database/search_template_builder.rb
36
38
  - lib/caruby/database/sql_executor.rb
37
39
  - lib/caruby/database/store_template_builder.rb
38
40
  - lib/caruby/database/writer.rb
39
- - lib/caruby/domain/annotatable.rb
40
- - lib/caruby/domain/annotation.rb
41
+ - lib/caruby/domain/attribute_initializer.rb
41
42
  - lib/caruby/domain/attribute_metadata.rb
43
+ - lib/caruby/domain/id_alias.rb
44
+ - lib/caruby/domain/inversible.rb
42
45
  - lib/caruby/domain/java_attribute_metadata.rb
43
46
  - lib/caruby/domain/merge.rb
44
47
  - lib/caruby/domain/properties.rb
@@ -46,16 +49,13 @@ files:
46
49
  - lib/caruby/domain/resource_attributes.rb
47
50
  - lib/caruby/domain/resource_dependency.rb
48
51
  - lib/caruby/domain/resource_introspection.rb
52
+ - lib/caruby/domain/resource_inverse.rb
49
53
  - lib/caruby/domain/resource_metadata.rb
50
54
  - lib/caruby/domain/resource_module.rb
51
55
  - lib/caruby/domain/uniquify.rb
52
- - lib/caruby/import/annotatable_class.rb
53
- - lib/caruby/import/annotation_class.rb
54
- - lib/caruby/import/annotation_module.rb
55
56
  - lib/caruby/import/java.rb
56
57
  - lib/caruby/migration/migratable.rb
57
58
  - lib/caruby/migration/migrator.rb
58
- - lib/caruby/migration/resource.rb
59
59
  - lib/caruby/migration/resource_module.rb
60
60
  - lib/caruby/migration/uniquify.rb
61
61
  - lib/caruby/util/attribute_path.rb
@@ -86,6 +86,7 @@ files:
86
86
  - lib/caruby/util/version.rb
87
87
  - lib/caruby/util/visitor.rb
88
88
  - lib/caruby/util/weak_hash.rb
89
+ - lib/caruby/yard/resource_metadata_handler.rb
89
90
  - History.txt
90
91
  - LEGAL
91
92
  - LICENSE
@@ -1,131 +0,0 @@
1
- require 'caruby/util/collection'
2
- require 'caruby/util/pretty_print'
3
- require 'caruby/domain/reference_visitor'
4
- require 'caruby/database/fetched_matcher'
5
- require 'caruby/database/store_template_builder'
6
-
7
- module CaRuby
8
- class Database
9
- # Merges database content sources into saved targets.
10
- class SavedMerger
11
- # @param [Database] database the database performing the save
12
- def initialize(database)
13
- @database = database
14
- # the save result matchers
15
- cr_mtchr = FetchedMatcher.new(:relaxed)
16
- upd_mtchr = FetchedMatcher.new
17
- # the save result merge visitors
18
- @cr_mrg_vstr = MergeVisitor.new(:matcher => cr_mtchr) { |src, tgt| mergeable_saved_attributes(tgt) }
19
- @upd_mrg_vstr = MergeVisitor.new(:matcher => upd_mtchr) { |src, tgt| mergeable_saved_attributes(tgt) }
20
- end
21
-
22
-
23
- # Merges the database content into the given saved domain object.
24
- # Dependents are merged recursively.
25
- #
26
- # @param [Resource] obj the saved domain object
27
- # @param [Resource] result the caCORE result
28
- # @return [Resource] the object representing the persistent state
29
- def merge(saved, result)
30
- # the sync source reflecting the database content
31
- src = saved_source(saved, result)
32
- # merge the source into obj, including all cascaded dependents
33
- merge_saved(saved, src)
34
- src
35
- end
36
-
37
- # @param [Resource] obj the saved domain object
38
- # @param [Resource] result the caCORE result domain object
39
- # @return [Resource] the source domain object which accurately reflects the database state
40
- # @see #fetch_saved?
41
- def saved_source(obj, result)
42
- # The true stored content might need to be fetched from the database.
43
- if obj.fetch_saved? then
44
- tmpl = result.copy(:identifier)
45
- logger.debug { "Fetching saved #{obj.qp} using template #{tmpl}..." }
46
- tmpl.find
47
- else
48
- result
49
- end
50
- end
51
-
52
- # Merges the content of the source domain object into the saved domain object obj.
53
- # If obj differs from source, then obj is resaved. Dependents are merged recursively.
54
- #
55
- # @param [Resource] obj the saved domain object
56
- # @param [Resource] source object holding the stored content
57
- def merge_saved(obj, source)
58
- logger.debug { "Merging database content #{source} into saved #{obj.qp}..." }
59
- visitor = @database.mergeable_autogenerated_operation? ? @cr_mrg_vstr : @upd_mrg_vstr
60
- visitor.visit(obj, source) do |tgt, src|
61
- logger.debug { "Saved #{obj.qp} merge visitor merged database content #{src.qp} into #{tgt.qp}..." }
62
- merge_saved_reference(tgt, src)
63
- end
64
- end
65
-
66
- # Sets the target snapshot attribute values from the given source, if different.
67
- #
68
- # @param [Resource] target the saved domain object
69
- # @param [Resource] source the domain object reflecting the database state
70
- # @return [Resource] the synced target
71
- def merge_saved_reference(target, source)
72
- # set each unsaved non-domain attribute from the source to reflect the database value
73
- target.copy_volatile_attributes(source)
74
-
75
- # take a snapshot of the saved target
76
- target.take_snapshot
77
- logger.debug { "A snapshot was taken of the saved #{target.qp}." }
78
-
79
- # the non-domain attribute => [target value, source value] difference hash
80
- diff = target.diff(source)
81
- # the difference attribute => source value hash, excluding nil source values
82
- dvh = diff.transform { |vdiff| vdiff.last }.compact
83
- return if dvh.empty?
84
- logger.debug { "Saved #{target} differs from database content #{source.qp} as follows: #{diff.filter_on_key { |attr| dvh.has_key?(attr) }.qp}" }
85
- logger.debug { "Setting saved #{target.qp} snapshot values from source values to reflect the database state: #{dvh.qp}..." }
86
- # update the snapshot from the source value to reflect the database state
87
- target.snapshot.merge!(dvh)
88
-
89
- target
90
- end
91
-
92
- # Returns the dependent attributes that can be copied from a save result to
93
- # the given save argument object. This method qualifies the obj class
94
- # {AttributeMetadata#copyable_saved_attributes} by whether the attribute is
95
- # actually auto-generated for the saved object, i.e. the object was itself
96
- # created or auto-generated. If obj was created or auto-generated, then
97
- # this method returns the {AttributeMetadata#copyable_saved_attributes}.
98
- # Otherwise, this method returns the {AttributeMetadata#cascaded_attributes}.
99
- #
100
- # @param [Resource] obj the domain object which was saved
101
- # @return [<Symbol>] the attributes to copy
102
- def mergeable_saved_attributes(obj)
103
- fa = obj.class.fetched_domain_attributes
104
- obj.suspend_lazy_loader do
105
- attrs = obj.class.cascaded_attributes.filter do |attr|
106
- fa.include?(attr) or not obj.send(attr).nil_or_empty?
107
- end
108
- if @database.mergeable_autogenerated_operation? then
109
- ag_attrs = mergeable_saved_autogenerated_attributes(obj)
110
- unless ag_attrs.empty? then
111
- logger.debug { "Adding #{obj.qp} mergeable saved auto-generated #{ag_attrs.to_series} to the merge set..." }
112
- attrs = attrs.to_set.merge(ag_attrs)
113
- end
114
- end
115
- logger.debug { "Mergeable saved #{obj.qp} attributes: #{attrs.qp}." } unless attrs.empty?
116
- attrs
117
- end
118
- end
119
-
120
- # Returns the autogenerated dependent attributes that can be copied from a save result to
121
- # the given save argument object.
122
- #
123
- # @param [Resource] obj the domain object which was saved
124
- # @return [<Symbol>] the attributes to copy, or nil if no such attributes
125
- def mergeable_saved_autogenerated_attributes(obj)
126
- attrs = obj.class.mergeable_saved_autogenerated_attributes
127
- attrs.reject { |attr| obj.send(attr).nil_or_empty? }
128
- end
129
- end
130
- end
131
- end
@@ -1,25 +0,0 @@
1
- require 'caruby/resource'
2
-
3
- module CaRuby
4
- # The Annotatable module marks a domain class as an anchor which holds at least one annotation attribute.
5
- module Annotatable
6
- include Resource
7
-
8
- # Dynamically creates a new annotation reference method with the given symbol if symbol is the camelized form of a
9
- # class in one of the Annotatable class's annotation modules.
10
- def method_missing(symbol, *args)
11
- name = symbol.to_s
12
- # remove trailing assignment = if present
13
- name.chop! if name =~ /=$/
14
- # the class with the camelized form of the name
15
- klass = self.class.annotation_class(name.camelize)
16
- # delegate to super to print an error if no class
17
- super if klass.nil?
18
- # add the annotation attribute
19
- klass.add_annotation(self.class)
20
- raise NotImplementedError.new("#{self.class.qp} annotation method not created: #{symbol}") unless respond_to?(symbol)
21
- #call the annotation attribute method
22
- send(symbol, *args)
23
- end
24
- end
25
- end
@@ -1,23 +0,0 @@
1
- require 'caruby/resource'
2
-
3
- module CaRuby
4
- # The Annotation module marks a domain object as an Annotation.
5
- module Annotation
6
- include Resource
7
-
8
- # Dynamically creates a new annotable owner attribute with the given symbol if symbol is an annotatable owner attribute
9
- # accessor method.
10
- #
11
- # @see #attribute_missing
12
- def method_missing(symbol, *args)
13
- name = symbol.to_s
14
- # remove trailing assignment = if present
15
- name.chop! if name =~ /=$/
16
- # try to make the owner attribute
17
- self.class.attribute_metadata(name.to_sym)
18
- # if we reached here, then the owner was created so verify and call the new method
19
- raise NoMethodError.new("#{name.demodulize} owner attribute #{name} created but accessor method not found: #{symbol}") unless method_defined?(symbol)
20
- send(symbol, *args)
21
- end
22
- end
23
- end
@@ -1,28 +0,0 @@
1
- require 'caruby/util/class'
2
- require 'caruby/util/collection'
3
- require 'caruby/import/annotation_module'
4
-
5
- module JavaImport
6
- # AnnotatableClass adds Annotation modules to an annotation anchor's domain module.
7
- module AnnotatableClass
8
-
9
- def self.extended(klass)
10
- klass.class_eval { include CaRuby::Annotatable }
11
- end
12
-
13
- def annotation_modules
14
- @annotation_modules ||= []
15
- end
16
-
17
- # Creates a new AnnotationModule anchored by this class for the given package and database service.
18
- def create_annotation_module(package, service)
19
- annotation_modules << AnnotationModule.create_annotation_module(self, package, service)
20
- end
21
-
22
- # Returns the class with the given unqualified name in one of this AnnotationClass's JavaImport::AnnotationModule
23
- # modules, or nil if no such class.
24
- def annotation_class(name)
25
- annotation_modules.detect_value { |mod| annotation_modules.const_get(name) rescue nil }
26
- end
27
- end
28
- end
@@ -1,27 +0,0 @@
1
- module JavaImport
2
- # AnnotationClass extends a domain class for an annotation class scoped by an annotation module.
3
- # The extended class must contain the +@anchor_class+ and +@annotation_module+ instance variables.
4
- module AnnotationClass
5
-
6
- # Dynamically creates a new reference attribute if the given attribute symbol is the underscore
7
- # form of this Annotation's anchor class.
8
- #
9
- #@param [Symbol] attribute the missing attribute
10
- def attribute_missing(attribute)
11
- # delegate to super to print an error if no class
12
- super unless attribute.to_s == anchor_class.qp.underscore
13
- # add the annotation attribute to the anchor class and the anchor attribute to this class
14
- anchor_class.add_annotation(self)
15
- end
16
-
17
- # @return [Class] the annotated class
18
- def anchor_class
19
- @anchor_class
20
- end
21
-
22
- # @return [Module] the module which scopes this AnnotationClass
23
- def annotation_module
24
- @annotation_module
25
- end
26
- end
27
- end
@@ -1,67 +0,0 @@
1
- require 'caruby/util/class'
2
- require 'caruby/util/collection'
3
- require 'caruby/import/importable'
4
- require 'caruby/import/annotation_class'
5
-
6
- module JavaImport
7
- # AnnotationModule creates annotation package modules within a domain module as a context for importing annotation classes.
8
- module AnnotationModule
9
- include Importable
10
-
11
- # Creates a new AnnotationModule in the given domain_module from the given annotation package and service.
12
- def self.create_annotation_module(anchor_class, package, service)
13
- domain_module = anchor_class.domain_module
14
- # make parent modules for each package component
15
- mod = package.split('.').inject(anchor_class.domain_module) do |parent, name|
16
- mod_id = name.camelize.to_sym
17
- if parent.const_defined?(mod_id) then
18
- parent.const_get(mod_id)
19
- else
20
- parent.const_set(mod_id, Module.new)
21
- end
22
- end
23
- # the terminal module is the AnnotationModule
24
- mod.extend(self)
25
- # initialize the java_package, service and empty access_properties
26
- mod.module_eval do
27
- @anchor_class = anchor_class
28
- @java_package = package
29
- @service = service
30
- @resource_module__props = CaRuby::Domain::Properties.new
31
- end
32
- mod_name = mod.name[anchor_class.domain_module.name.length..-1]
33
- logger.debug { "Created annotation module #{mod}." }
34
- mod
35
- end
36
-
37
- def java_package
38
- @java_package
39
- end
40
-
41
- def service
42
- @service
43
- end
44
-
45
- def anchor_class
46
- @anchor_class
47
- end
48
-
49
- def access_properties
50
- @resource_module__props
51
- end
52
-
53
- # Imports the domain Java class with specified class_name by delegating to Importable and
54
- # augmenting the importer to include CaRuby::Annotation in each imported class.
55
- def import_domain_class(class_name)
56
- anchor_class = @anchor_class
57
- ann_mod = self
58
- klass = super(class_name) do
59
- include CaRuby::Annotation
60
- @anchor_class = anchor_class
61
- @annotation_module = ann_mod
62
- yield if block_given?
63
- end
64
- klass.extend(AnnotationClass)
65
- end
66
- end
67
- end
@@ -1,8 +0,0 @@
1
- require 'caruby/resource'
2
- require 'caruby/migration/migratable'
3
-
4
- module CaRuby
5
- module Resource
6
- include Migratable
7
- end
8
- end