yogo-project 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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