yogo-project 0.3.2

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 (61) hide show
  1. data/.document +5 -0
  2. data/.gitignore +27 -0
  3. data/Gemfile +34 -0
  4. data/Gemfile.lock +198 -0
  5. data/LICENSE +20 -0
  6. data/README.rdoc +17 -0
  7. data/Rakefile +56 -0
  8. data/VERSION +1 -0
  9. data/features/step_definitions/yogo_project_steps.rb +0 -0
  10. data/features/support/env.rb +1 -0
  11. data/features/yogo_project.feature +9 -0
  12. data/lib/datamapper/adapters/postgres.rb +9 -0
  13. data/lib/datamapper/adapters/sqlite.rb +9 -0
  14. data/lib/yogo-project.rb +2 -0
  15. data/lib/yogo/collection.rb +12 -0
  16. data/lib/yogo/collection/asset.rb +12 -0
  17. data/lib/yogo/collection/asset/model.rb +11 -0
  18. data/lib/yogo/collection/asset/model_configuration.rb +21 -0
  19. data/lib/yogo/collection/asset/model_properties.rb +47 -0
  20. data/lib/yogo/collection/base.rb +69 -0
  21. data/lib/yogo/collection/base/collection_repository.rb +21 -0
  22. data/lib/yogo/collection/base/model.rb +20 -0
  23. data/lib/yogo/collection/base/model_collection_context.rb +25 -0
  24. data/lib/yogo/collection/base/model_configuration.rb +34 -0
  25. data/lib/yogo/collection/data.rb +61 -0
  26. data/lib/yogo/collection/data/model.rb +72 -0
  27. data/lib/yogo/collection/data/model_configuration.rb +42 -0
  28. data/lib/yogo/collection/data/model_properties.rb +15 -0
  29. data/lib/yogo/collection/field_view.rb +26 -0
  30. data/lib/yogo/collection/form.rb +22 -0
  31. data/lib/yogo/collection/property.rb +127 -0
  32. data/lib/yogo/collection/static.rb +13 -0
  33. data/lib/yogo/collection/static/model_configuration.rb +31 -0
  34. data/lib/yogo/configuration.rb +9 -0
  35. data/lib/yogo/datamapper/model/common/properties.rb +16 -0
  36. data/lib/yogo/datamapper/model/configuration.rb +31 -0
  37. data/lib/yogo/datamapper/model/operations/add.rb +34 -0
  38. data/lib/yogo/datamapper/model/operations/clear.rb +29 -0
  39. data/lib/yogo/datamapper/model/stored/configuration.rb +25 -0
  40. data/lib/yogo/datamapper/repository_manager.rb +30 -0
  41. data/lib/yogo/datamapper/repository_manager/model.rb +40 -0
  42. data/lib/yogo/datamapper/repository_manager/resource.rb +124 -0
  43. data/lib/yogo/example/dynamic/project_full.rb +48 -0
  44. data/lib/yogo/example/dynamic/project_remix.rb +16 -0
  45. data/lib/yogo/example/voeis/managed/data_stream.rb +39 -0
  46. data/lib/yogo/example/voeis/managed/site.rb +51 -0
  47. data/lib/yogo/example/voeis/project.rb +57 -0
  48. data/lib/yogo/operation.rb +49 -0
  49. data/lib/yogo/project.rb +32 -0
  50. data/lib/yogo/property_ext.rb +7 -0
  51. data/spec/resource/.gitdir +0 -0
  52. data/spec/resource/text_file_asset.txt +1 -0
  53. data/spec/spec_helper.rb +49 -0
  54. data/spec/yogo/all_collection_data_models_spec.rb +34 -0
  55. data/spec/yogo/all_collection_managers_spec.rb +18 -0
  56. data/spec/yogo/all_collections_spec.rb +54 -0
  57. data/spec/yogo/all_data_collections_spec.rb +51 -0
  58. data/spec/yogo/asset_collection_spec.rb +28 -0
  59. data/spec/yogo/data_collection_spec.rb +16 -0
  60. data/yogo-project.gemspec +128 -0
  61. metadata +222 -0
@@ -0,0 +1,48 @@
1
+ require 'yogo/configuration'
2
+ require 'yogo/datamapper/model/configuration'
3
+ require 'yogo/datamapper/model/common/properties'
4
+ require 'dm-types/yaml'
5
+
6
+ DataMapper.setup(:default, :adapter => 'sqlite3', :database => 'dynamic_project.db')
7
+
8
+ class ProjectFull
9
+ include DataMapper::Resource
10
+
11
+ Yogo::DataMapper::Model::Common::Properties::UUIDKey[self]
12
+
13
+ property :name, String, :required => true
14
+
15
+ has n, :managed_models
16
+ end
17
+
18
+
19
+ class ManagedModel
20
+ include DataMapper::Resource
21
+ include Yogo::DataMapper::Model::Configuration
22
+
23
+ Yogo::DataMapper::Model::Common::Properties::UUIDKey[self]
24
+ property :name, String, :required => true
25
+
26
+ has n, :model_operations
27
+
28
+ def operation_definitions
29
+ model_operations.map{|model_op| model_op.to_a }
30
+ end
31
+
32
+ def update(model=nil)
33
+ to_proc.call(model || (@_model ||= DataMapper::Model.new))
34
+ end
35
+ end
36
+
37
+ class ModelOperation
38
+ include DataMapper::Resource
39
+
40
+ Yogo::DataMapper::Model::Common::Properties::UUIDKey[self]
41
+
42
+ property :operation, String, :required => true
43
+ property :parameters, Yaml, :default => lambda{|*args| [] }
44
+
45
+ def to_a
46
+ [self.operation, self.parameters].flatten
47
+ end
48
+ end
@@ -0,0 +1,16 @@
1
+ require 'yogo/datamapper/dynamic/stored/configuration'
2
+
3
+
4
+ class ProjectRemix
5
+ include ::DataMapper::Resource
6
+
7
+ property :id, UUID, :key => true, :default => lambda { Yogo::Configuration.random_uuid }
8
+ property :name, String, :required => true
9
+
10
+ without_auto_validations do
11
+ remix n, 'Yogo::DataMapper::Dynamic::Stored::Configuration', :as => :model_configurations, :model => 'ProjectModelConfiguration'
12
+ enhance :configuration do
13
+ property :project_id, UUID
14
+ end
15
+ end
16
+ end # ProjectRemix
@@ -0,0 +1,39 @@
1
+ # Yogo Data Management Toolkit
2
+ # Copyright (c) 2010 Montana State University
3
+ #
4
+ # License -> see license.txt
5
+ #
6
+ # FILE: data_stream.rb
7
+ # The Data Stream model is where the streaming data parsing templates are stores.
8
+ #
9
+
10
+ # Class for a Yogo Project. A project contains a name, a description, and access to all of the models
11
+ # that are part of the project.
12
+ module Yogo
13
+ module Voeis
14
+ module Managed
15
+ class DataStream
16
+ include ::DataMapper::Resource
17
+
18
+ property :id, UUID, :key => true, :default => lambda { UUIDTools::UUID.timestamp_create }
19
+
20
+ property :name, String, :required => true, :unique => true
21
+ property :description, Text, :required => false
22
+ property :filename, String, :required => true, :length => 512
23
+ property :start_line, Integer, :required => true, :default => 0
24
+
25
+ property :project_id, Integer, :required =>true, :default => 1
26
+
27
+ validates_uniqueness_of :name
28
+
29
+ #before :destroy, :delete_data_stream_columns!
30
+
31
+ has n, :sites, :through => Resource
32
+ # has n, :data_stream_columns, :model => "DataStreamColumn", :through => Resource
33
+
34
+
35
+
36
+ end # DataStream
37
+ end # Managed
38
+ end # Voeis
39
+ end # Yogo
@@ -0,0 +1,51 @@
1
+ # Sites TODO- validate the best practices below
2
+ #
3
+ # This is a "Monitoring Site Locations"
4
+ # The Sites table provides information giving the spatial location at which data values have been
5
+ # collected.
6
+ # The following rules and best practices should be followed when populating this table:
7
+ # * The SiteID field is the primary key, must be a unique integer, and cannot be NULL. This
8
+ # field should be implemented as an auto number/identity field.
9
+ # * The SiteCode field must contain a text code that uniquely identifies each site. The values
10
+ # in this field should be unique and can be an alternate key for the table. SiteCodes cannot
11
+ # contain any characters other than A-Z (case insensitive), 0-9, period “.”, dash “-“, and
12
+ # underscore “_”.
13
+ # * The LatLongDatumID must reference a valid SpatialReferenceID from the
14
+ # SpatialReferences controlled vocabulary table. If the datum is unknown, a default value
15
+ # of 0 is used.
16
+ # * If the Elevation_m field is populated with a numeric value, a value must be specified in
17
+ # the VerticalDatum field. The VerticalDatum field can only be populated using terms
18
+ # from the VerticalDatumCV table. If the vertical datum is unknown, a value of
19
+ # “Unknown” is used.
20
+ # * If the LocalX and LocalY fields are populated with numeric values, a value must be
21
+ # specified in the LocalProjectionID field. The LocalProjectionID must reference a valid
22
+ # SpatialReferenceID from the SpatialReferences controlled vocabulary table. If the spatial
23
+ # reference system of the local coordinates is unknown, a default value of 0 is used.
24
+ #
25
+ module Yogo
26
+ module Voeis
27
+ module Managed
28
+ class Site
29
+ include ::DataMapper::Resource
30
+
31
+ property :id, UUID, :key => true, :default => lambda { UUIDTools::UUID.timestamp_create }
32
+ property :site_code, String, :required => true
33
+ property :site_name, String, :required => true
34
+ property :latitude, Float, :required => true
35
+ property :longitude, Float, :required => true
36
+ property :lat_long_datum_id, Integer, :required => true, :default => 0
37
+ property :elevation_m, Float, :required => false
38
+ property :vertical_datum, String, :required => false
39
+ property :local_x, Float, :required => false
40
+ property :local_y, Float, :required => false
41
+ property :local_projection_id, Integer, :required => false
42
+ property :pos_accuracy_m, Float, :required => false
43
+ property :state, String, :required => false
44
+ property :country, String, :required => false
45
+ property :comments, String, :required => false
46
+
47
+ has n, :data_streams, :through => Resource
48
+ end # Site
49
+ end # Managed
50
+ end # Voeis
51
+ end # Yogo
@@ -0,0 +1,57 @@
1
+ require 'dm-core'
2
+ require 'dm-types/uuid'
3
+
4
+ require 'yogo/datamapper/repository_manager'
5
+ require 'yogo/example/voeis/managed/site'
6
+ require 'yogo/example/voeis/managed/data_stream'
7
+
8
+ module Yogo
9
+ module Voeis
10
+ class Project
11
+ include ::DataMapper::Resource
12
+ include Yogo::DataMapper::RepositoryManager
13
+
14
+ property :id, UUID, :key => true, :default => lambda { UUIDTools::UUID.timestamp_create }
15
+ property :name, String, :required => true
16
+ property :description, String
17
+
18
+ def self.manage(klass)
19
+ @managed_models ||= []
20
+ unless @managed_models.include?(klass)
21
+ @managed_models << klass
22
+ end
23
+ @managed_models
24
+ end
25
+
26
+ def self.managed_models
27
+ @managed_models
28
+ end
29
+
30
+
31
+ def managed_repository_name
32
+ ActiveSupport::Inflector.tableize(id.to_s).to_sym
33
+ end
34
+
35
+ def adapter_config
36
+ {
37
+ :adapter => 'sqlite',
38
+ :database => "voeis-project-#{managed_repository_name}.db"
39
+ }
40
+ end
41
+
42
+ def prepare_models
43
+ adapter # ensure the adapter exists or is setup
44
+ managed_repository.scope {
45
+ self.class.managed_models.each do |klass|
46
+ klass.auto_upgrade!
47
+ end
48
+ }
49
+ end
50
+
51
+ after :save, :prepare_models
52
+
53
+ manage Managed::Site
54
+ manage Managed::DataStream
55
+ end # Project
56
+ end # Voeis
57
+ end # Yogo
@@ -0,0 +1,49 @@
1
+ require 'facets/proc/curry'
2
+ require 'facets/proc/compose'
3
+
4
+ X = :partial_unspecified_argument
5
+
6
+ module Yogo
7
+ class Operation < Proc
8
+
9
+ def self.on(type, &block)
10
+ op = self.new(&block)
11
+ op.instance_eval{ self.type = type }
12
+ op
13
+ end
14
+
15
+ def call(*args)
16
+ x = args.first
17
+ raise "Can only invoke on #{type}" if type && !x.is_a?(type)
18
+ super(*args)
19
+ end
20
+
21
+
22
+
23
+ private
24
+ attr_accessor :type
25
+ end # Operation
26
+
27
+ class ::Proc
28
+ def partial(*args)
29
+ Proc.new do |*spice|
30
+ result = args.collect do |a|
31
+ X == a ? spice.shift : a
32
+ end
33
+ call(*result)
34
+ end
35
+ end
36
+ end
37
+
38
+ module Operations
39
+ def self.[](op_name)
40
+ op_name.split("::").reduce(self) do |namespace, const|
41
+ if namespace && namespace.const_defined?(const)
42
+ namespace.const_get(const)
43
+ else
44
+ nil
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end # Yogo
@@ -0,0 +1,32 @@
1
+ require 'dm-core'
2
+ require 'dm-types/uuid'
3
+ require 'yogo/collection'
4
+
5
+ module Yogo
6
+ class Project
7
+ include ::DataMapper::Resource
8
+
9
+ property :id, UUID, :key => true, :default => lambda { |p,r| UUIDTools::UUID.timestamp_create }
10
+ property :name, String, :required => true
11
+ property :description, Text
12
+
13
+ has n, :data_collections, :model => 'Yogo::Collection::Data', :child_key => [:project_id]
14
+
15
+ chainable do
16
+ def as_json(options={})
17
+ {
18
+ :id => self.id.to_s,
19
+ :name => self.name,
20
+ :description => self.description,
21
+ :data_collections => self.data_collections.map{|c| c.id.to_s }
22
+ }
23
+ end
24
+
25
+ def update_attributes(hash)
26
+ attrs = {}
27
+ attrs[:name] = hash[:name] || hash['name'] || self.name
28
+ attrs[:description] = hash[:description] || hash['description'] || self.description
29
+ end
30
+ end
31
+ end # Project
32
+ end # Yogo
@@ -0,0 +1,7 @@
1
+ unless ::DataMapper::Property.accepted_options.include?(:label)
2
+ ::DataMapper::Property.accept_options(:label)
3
+ end
4
+
5
+ unless ::DataMapper::Property.accepted_options.include?(:hidden)
6
+ ::DataMapper::Property.accept_options(:hidden)
7
+ end
File without changes
@@ -0,0 +1 @@
1
+ Example of an asset.
@@ -0,0 +1,49 @@
1
+ # Standard requirements for Bundler management
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+
5
+ # Load the bundler gemset
6
+ Bundler.setup(:default, ENV['RACK_ENV'] || :test )
7
+
8
+ # Mess with load paths
9
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
10
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
11
+
12
+ require 'rspec/core'
13
+ require 'autotest/rspec2'
14
+ require 'rack/test'
15
+ require 'rack/mock'
16
+
17
+ require 'data_mapper'
18
+ require 'dm-postgres-adapter'
19
+ require 'dm-sqlite-adapter'
20
+
21
+ require 'yogo-project'
22
+
23
+ require 'yogo/project'
24
+ require 'yogo/collection'
25
+
26
+ Dir[File.join(File.dirname(__FILE__), "helpers", "**/*.rb")].each do |f|
27
+ require f
28
+ end
29
+
30
+ Dir[File.join(File.dirname(__FILE__), "factories", "**/*.rb")].each do |f|
31
+ require f
32
+ end
33
+
34
+ SPEC_DIR = File.expand_path(File.dirname(__FILE__))
35
+ SPEC_TMP_DIR = File.join(SPEC_DIR, 'tmp')
36
+ SPEC_RES_DIR = File.join(SPEC_DIR, 'resource')
37
+
38
+ DB_URL = "sqlite://#{SPEC_TMP_DIR}/projects.db"
39
+ COLLECTION_URL = "sqlite://#{SPEC_TMP_DIR}/collections.db"
40
+
41
+ Rspec.configure do |config|
42
+ config.before(:suite) do
43
+ DataMapper::Model.raise_on_save_failure = true
44
+ DataMapper::Logger.new('log/datamapper.log', :debug)
45
+ @default = ::DataMapper.setup(:default, DB_URL)
46
+ @collection_data = ::DataMapper.setup(:collection_data, COLLECTION_URL)
47
+ ::DataMapper.finalize.auto_migrate!
48
+ end
49
+ end
@@ -0,0 +1,34 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ shared_examples_for "All Collection Data Models" do
4
+ it "should be a datamapper model" do
5
+ @data_model.should be_a_kind_of(::DataMapper::Model)
6
+ end
7
+
8
+ it "should use the collection data_repository" do
9
+ @collection.scope do
10
+ @data_model.repository.should == @data_model.collection.collection_repository
11
+ end
12
+
13
+ end
14
+
15
+ describe "core properties" do
16
+ it "should include :id" do
17
+ @collection.scope do
18
+ @data_model.properties[:id].should_not be_nil
19
+ end
20
+ end
21
+
22
+ it "should include :created_at" do
23
+ @collection.scope do
24
+ @data_model.properties[:created_at].should_not be_nil
25
+ end
26
+ end
27
+
28
+ it "should include :updated_at" do
29
+ @collection.scope do
30
+ @data_model.properties[:updated_at].should_not be_nil
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ shared_examples_for "All Collection Managers" do
4
+
5
+ describe "class" do
6
+ before(:each) do
7
+ @manager_class = @manager.class
8
+ end
9
+
10
+ it "should be a datamapper model" do
11
+ @manager_class.should be_a_kind_of(::DataMapper::Model)
12
+ end
13
+ end
14
+
15
+ it "should have a repository for collections"
16
+ it "should have collections"
17
+
18
+ end
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ shared_examples_for "All Collections" do
4
+ it "should have a name" do
5
+ @collection.name.should be_a_kind_of(String)
6
+ @collection.name.should_not be_empty
7
+ end
8
+
9
+ it "should allow name to be changed" do
10
+ new_name = "Cercal Cell DB"
11
+
12
+ @collection.name = new_name
13
+ @collection.should be_valid
14
+ @collection.save.should be_true
15
+ @collection.name.should == new_name
16
+ end
17
+
18
+ it "should allow description to be changed" do
19
+ new_description = "Example Database"
20
+ @collection.description = new_description
21
+ @collection.should be_valid
22
+ @collection.save.should be_true
23
+ @collection.description.should == new_description
24
+ end
25
+
26
+
27
+ it "should have a collection_repository" do
28
+ @collection.should respond_to(:collection_repository)
29
+ end
30
+
31
+ describe "collection_repository" do
32
+ it "should be a datamapper respository" do
33
+ @collection.collection_repository.should be_a_kind_of(DataMapper::Repository)
34
+ end
35
+ end
36
+
37
+ it "should have a data_model" do
38
+ @collection.should respond_to(:data_model)
39
+ end
40
+
41
+ describe "data_model" do
42
+ before(:each) do
43
+ @data_model = @collection.data_model
44
+ end
45
+
46
+ it_should_behave_like "All Collection Data Models"
47
+ end
48
+
49
+ it "should have items" do
50
+ @collection.should respond_to(:items)
51
+ end
52
+
53
+
54
+ end