infopark_cloud_connector 6.8.1 → 6.8.1.26.236500544

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,9 @@
1
+ Description:
2
+ Creates a new CMS migration.
3
+
4
+ Example:
5
+ rails generate cms:migration CreateExample
6
+ rails generate cms:migration create_example
7
+
8
+ This will create:
9
+ cms/migrate/[timestamp]_create_example.rb
@@ -0,0 +1,15 @@
1
+ module Cms
2
+ class MigrationGenerator < ::Rails::Generators::NamedBase
3
+ include ::Rails::Generators::Migration
4
+
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ def self.next_migration_number(dirname)
8
+ Time.now.utc.strftime('%Y%m%d%H%M%S')
9
+ end
10
+
11
+ def create_migration_file
12
+ migration_template('migration.rb', "cms/migrate/#{file_name}")
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,17 @@
1
+ class <%= class_name %> < ::RailsConnector::Migration
2
+ def up
3
+ # get_attribute('test')
4
+ # create_attribute(:name => 'test', :type => :string)
5
+ # update_attribute('test', :title => 'Test Title')
6
+ # delete_attribute('test')
7
+
8
+ # get_obj_class('Test')
9
+ # create_obj_class(:name => 'Test', :type => :publication)
10
+ # update_obj_class('Test', :title => 'Test Title')
11
+
12
+ # get_obj('a1b2c3')
13
+ # create_obj(:_path => '/test', :_obj_class => 'Test')
14
+ # update_obj('a1b2c3', :title => 'Test Title')
15
+ # delete_obj('a1b2c3')
16
+ end
17
+ end
@@ -0,0 +1,2 @@
1
+ # ::RailsConnector::Migration is just a shortcut
2
+ ::RailsConnector::Migration = ::RailsConnector::Migrations::Migration
@@ -0,0 +1,12 @@
1
+ module RailsConnector
2
+ module Migrations
3
+ extend ActiveSupport::Autoload
4
+
5
+ autoload :Migration
6
+ autoload :Migrator
7
+ autoload :MigrationStore
8
+ autoload :MigrationDsl
9
+ autoload :CmsBackend
10
+ autoload :WorkspaceLock
11
+ end
12
+ end
@@ -0,0 +1,98 @@
1
+ module RailsConnector
2
+ module Migrations
3
+ class CmsBackend
4
+ def read
5
+ obj = find_migration_store_obj
6
+
7
+ if obj
8
+ obj[attribute_name]
9
+ else
10
+ initial_value
11
+ end
12
+ end
13
+
14
+ def save(value)
15
+ CmsRestApi.put(
16
+ endpoint("objs/#{migration_store_obj.id}"),
17
+ :obj => {
18
+ attribute_name => value
19
+ }
20
+ )
21
+ end
22
+
23
+ private
24
+
25
+ def create
26
+ # Create attribute
27
+ CmsRestApi.post(
28
+ endpoint('attributes'),
29
+ :attribute => {
30
+ :name => attribute_name,
31
+ :type => :text,
32
+ }
33
+ )
34
+
35
+ # Create obj class
36
+ CmsRestApi.post(
37
+ endpoint('obj_classes'),
38
+ :obj_class => {
39
+ :name => obj_class_name,
40
+ :attributes => [attribute_name],
41
+ :type => :publication,
42
+ :title => obj_class_name,
43
+ }
44
+ )
45
+
46
+ # Create obj
47
+ CmsRestApi.post(
48
+ endpoint('objs'),
49
+ :obj => {
50
+ :_path => path,
51
+ :_obj_class => obj_class_name,
52
+ attribute_name => initial_value,
53
+ }
54
+ )
55
+
56
+ # Deactivate obj class
57
+ CmsRestApi.put(
58
+ endpoint("obj_classes/#{obj_class_name}"),
59
+ :obj_class => {
60
+ :is_active => false,
61
+ }
62
+ )
63
+ end
64
+
65
+ def migration_store_obj
66
+ unless find_migration_store_obj
67
+ create
68
+ end
69
+
70
+ find_migration_store_obj
71
+ end
72
+
73
+ def find_migration_store_obj
74
+ Obj.find_by_path(path)
75
+ end
76
+
77
+ def attribute_name
78
+ 'versions'
79
+ end
80
+
81
+ def obj_class_name
82
+ 'MigrationStore'
83
+ end
84
+
85
+ def path
86
+ '/_internal/migration-store'
87
+ end
88
+
89
+ def initial_value
90
+ ''
91
+ end
92
+
93
+ def endpoint(path)
94
+ "revisions/#{Workspace.current.revision_id}/#{path}"
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,43 @@
1
+ module RailsConnector
2
+ module Migrations
3
+ # CMS Migrations can alter the structure and content of the CMS and allow
4
+ # other developers to simultaneously apply changes. Migrations provide a set
5
+ # of methods to create, update or delete CMS objects, attributes and object
6
+ # classes.
7
+ #
8
+ # @example Simple Migration
9
+ #
10
+ # class CreateTestAttribute < RailsConnector::Migrations::Migration
11
+ # def up
12
+ # create_attribute(:name => 'test', :type => 'string')
13
+ # end
14
+ # end
15
+ class Migration
16
+ include MigrationDsl
17
+
18
+ attr_accessor :name
19
+ attr_accessor :version
20
+
21
+ def initialize(name, version)
22
+ @name = name
23
+ @version = version.to_i
24
+ end
25
+
26
+ def migrate
27
+ announce 'migrating'
28
+
29
+ time = Benchmark.measure { up }
30
+
31
+ announce 'migrated (%.4fs)' % time.real; puts
32
+ end
33
+
34
+ private
35
+
36
+ def announce(message)
37
+ text = "#{version} #{name}: #{message}"
38
+ length = [0, 75 - text.length].max
39
+ puts('== %s %s' % [text, '=' * length])
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,176 @@
1
+ module RailsConnector
2
+ module Migrations
3
+ module MigrationDsl
4
+ # Creates a CMS attribute.
5
+ #
6
+ # @example Create "test" Attribute
7
+ #
8
+ # create_attribute(:name => 'test', :type => 'string')
9
+ #
10
+ # @param attributes [Hash] The attributes and their values of the new
11
+ # CMS attribute.
12
+ #
13
+ # @return nothing
14
+ def create_attribute(attributes = {})
15
+ endpoint = "revisions/#{Workspace.current.revision_id}/attributes"
16
+
17
+ CmsRestApi.post(endpoint, :attribute => attributes)
18
+ end
19
+
20
+ # Creates a CMS object.
21
+ #
22
+ # @example Create "/test" Object
23
+ #
24
+ # create_obj(:_path => '/test', :_obj_class => 'Test')
25
+ #
26
+ # @param attributes [Hash] The attributes and their values of the new
27
+ # CMS object.
28
+ #
29
+ # @return nothing
30
+ def create_obj(attributes = {})
31
+ endpoint = "revisions/#{Workspace.current.revision_id}/objs"
32
+
33
+ CmsRestApi.post(endpoint, :obj => attributes)
34
+ end
35
+
36
+ # Creates a CMS object class.
37
+ #
38
+ # @example Create "Test" Object Class
39
+ #
40
+ # create_obj_class(:name => 'Test', :type => 'publication')
41
+ #
42
+ # @param attributes [Hash] The attributes and their values of the new
43
+ # CMS object class.
44
+ #
45
+ # @return nothing
46
+ def create_obj_class(attributes = {})
47
+ endpoint = "revisions/#{Workspace.current.revision_id}/obj_classes"
48
+
49
+ CmsRestApi.post(endpoint, :obj_class => attributes)
50
+ end
51
+
52
+ # Deletes a CMS attribute.
53
+ #
54
+ # @example Delete "test" Attribute
55
+ #
56
+ # delete_attribute('test')
57
+ #
58
+ # @param id [String] The ID of the CMS attribute.
59
+ #
60
+ # @return nothing
61
+ def delete_attribute(id)
62
+ endpoint = "revisions/#{Workspace.current.revision_id}/attributes/#{id}"
63
+
64
+ CmsRestApi.delete(endpoint)
65
+ end
66
+
67
+ # Deletes a CMS object with the given id.
68
+ #
69
+ # @example Deletes "a1b2c3" Object
70
+ #
71
+ # delete_obj('a1b2c3')
72
+ #
73
+ # @param id [String] The ID of the CMS object.
74
+ #
75
+ # @return nothing
76
+ def delete_obj(id)
77
+ endpoint = "revisions/#{Workspace.current.revision_id}/objs/#{id}"
78
+
79
+ CmsRestApi.delete(endpoint)
80
+ end
81
+
82
+ # Fetches all attribute attributes and their values.
83
+ #
84
+ # @example Get all attributes for the attribute "test"
85
+ #
86
+ # get_attribute('test')
87
+ #
88
+ # @param id [String] The ID of the attribute.
89
+ #
90
+ # @return [Hash] a hash with attributes and their values.
91
+ def get_attribute(id)
92
+ endpoint = "revisions/#{Workspace.current.revision_id}/attributes/#{id}"
93
+
94
+ CmsRestApi.get(endpoint)
95
+ end
96
+
97
+ # Fetches all object attributes and their values.
98
+ #
99
+ # @example Get all attributes for the obj with id "abc123"
100
+ #
101
+ # get_obj('abc123')
102
+ #
103
+ # @param id [String] The ID of the CMS object.
104
+ #
105
+ # @return [Hash] a hash with attributes and their values.
106
+ def get_obj(id)
107
+ endpoint = "revisions/#{Workspace.current.revision_id}/objs/#{id}"
108
+
109
+ CmsRestApi.get(endpoint)
110
+ end
111
+
112
+ # Fetches all object class attributes and their values.
113
+ #
114
+ # @example Get all attributes for the object class "Test"
115
+ #
116
+ # get_obj_class('Test')
117
+ #
118
+ # @param id [String] The ID of the object class.
119
+ #
120
+ # @return [Hash] a hash with attributes and their values.
121
+ def get_obj_class(id)
122
+ endpoint = "revisions/#{Workspace.current.revision_id}/obj_classes/#{id}"
123
+
124
+ CmsRestApi.get(endpoint)
125
+ end
126
+
127
+ # Updates a CMS attribute.
128
+ #
129
+ # @example Update the title of the "test" Attribute
130
+ #
131
+ # update_attribute(:title => 'Test Title')
132
+ #
133
+ # @param id [String] The ID of the attribute.
134
+ # @param attributes [Hash] The updated attributes and their values.
135
+ #
136
+ # @return nothing
137
+ def update_attribute(id, attributes = {})
138
+ endpoint = "revisions/#{Workspace.current.revision_id}/attributes/#{id}"
139
+
140
+ CmsRestApi.put(endpoint, :attribute => attributes)
141
+ end
142
+
143
+ # Updates a CMS object.
144
+ #
145
+ # @example Update the title of the "a1b2c3" Object
146
+ #
147
+ # update_attribute('a1b2c3', :title => 'Test Title')
148
+ #
149
+ # @param id [String] The ID of the CMS object.
150
+ # @param attributes [Hash] The updated attributes and their values.
151
+ #
152
+ # @return nothing
153
+ def update_obj(id, attributes = {})
154
+ endpoint = "revisions/#{Workspace.current.revision_id}/objs/#{id}"
155
+
156
+ CmsRestApi.put(endpoint, :obj => attributes)
157
+ end
158
+
159
+ # Updates a CMS object class.
160
+ #
161
+ # @example Update the title of the "Test" Object Class
162
+ #
163
+ # update_obj_class('Test', :title => 'Test Title')
164
+ #
165
+ # @param id [String] The ID of the CMS object class.
166
+ # @param attributes [Hash] The updated attributes and their values.
167
+ #
168
+ # @return nothing
169
+ def update_obj_class(id, attributes = {})
170
+ endpoint = "revisions/#{Workspace.current.revision_id}/obj_classes/#{id}"
171
+
172
+ CmsRestApi.put(endpoint, :obj_class => attributes)
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,23 @@
1
+ require 'singleton'
2
+
3
+ module RailsConnector
4
+ module Migrations
5
+ class MigrationStore
6
+ include Singleton
7
+
8
+ def backend
9
+ @backend ||= CmsBackend.new
10
+ end
11
+
12
+ def versions
13
+ @versions ||= MultiJson.load(backend.read.presence || '[]')
14
+ end
15
+
16
+ def add_version(version)
17
+ versions << version
18
+
19
+ backend.save(MultiJson.dump(versions))
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,123 @@
1
+ module RailsConnector
2
+ module Migrations
3
+ class Migrator
4
+ attr_reader :migrations
5
+ attr_reader :workspace_lock
6
+
7
+ def initialize
8
+ @migrations = determine_migrations
9
+ @migration_store = MigrationStore.instance
10
+ @workspace_lock = WorkspaceLock.instance
11
+
12
+ validate
13
+ end
14
+
15
+ def migrate
16
+ workspace.as_current do
17
+ runnable.each do |migration|
18
+ migration.migrate
19
+ @migration_store.add_version(migration.version)
20
+ end
21
+ end
22
+ end
23
+
24
+ def publish
25
+ remove_workspace_with do
26
+ CmsRestApi.put("workspaces/#{workspace.id}/publish", {})
27
+ end
28
+ end
29
+
30
+ def abort
31
+ remove_workspace_with do
32
+ CmsRestApi.delete("workspaces/#{workspace.id}")
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def workspace
39
+ workspace = migration_workspace
40
+
41
+ if workspace
42
+ if workspace_lock.exists?
43
+ workspace_lock.validate(workspace)
44
+ end
45
+ else
46
+ CmsRestApi.post('workspaces', :workspace => { :title => 'rtc', :id => 'rtc' })
47
+
48
+ workspace = migration_workspace
49
+ workspace_lock.write(workspace)
50
+ end
51
+
52
+ workspace
53
+ end
54
+
55
+ def migration_workspace
56
+ Workspace.find('rtc')
57
+ rescue ResourceNotFound
58
+ end
59
+
60
+ def remove_workspace_with(&block)
61
+ workspace = migration_workspace
62
+
63
+ if workspace
64
+ workspace_lock.validate(workspace)
65
+
66
+ yield
67
+
68
+ workspace_lock.remove
69
+ else
70
+ raise RailsConnectorError.new('Migration workspace does not exist')
71
+ end
72
+ end
73
+
74
+ def determine_migrations
75
+ files = Dir[*migrations_paths.map { |path| "#{path}/**/[0-9]*_*.rb" }]
76
+
77
+ migrations = files.map do |file|
78
+ version, name = file.scan(/([0-9]+)_([_a-z0-9]*)\.rb\z/).first
79
+
80
+ unless version
81
+ raise RailsConnectorError.new("Illegal name for migration file: #{file}\n\t(only lower case letters, numbers, and '_' allowed)")
82
+ end
83
+
84
+ version = version
85
+ name = name.camelize
86
+
87
+ require(File.expand_path(file))
88
+ name.constantize.new(name, version)
89
+ end
90
+
91
+ migrations.sort_by(&:version)
92
+ end
93
+
94
+ def migrations_paths
95
+ ["#{Rails.root}/cms/migrate"]
96
+ end
97
+
98
+ def runnable
99
+ migrations.reject do |migration|
100
+ migrated_versions.include?(migration.version)
101
+ end
102
+ end
103
+
104
+ def migrated_versions
105
+ @migration_store.versions
106
+ end
107
+
108
+ def validate
109
+ name, _ = migrations.group_by(&:name).find { |_, value| value.length > 1 }
110
+
111
+ if name
112
+ raise RailsConnectorError.new("Multiple migrations have the name #{name}")
113
+ end
114
+
115
+ version, _ = migrations.group_by(&:version).find { |_, value| value.length > 1 }
116
+
117
+ if version
118
+ raise RailsConnectorError.new("Multiple migrations have the version number #{version}")
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,38 @@
1
+ require 'singleton'
2
+
3
+ module RailsConnector
4
+ module Migrations
5
+ class WorkspaceLock
6
+ include Singleton
7
+
8
+ def validate(workspace)
9
+ unless exists? && workspace.revision_id == File.read(filename)
10
+ raise RailsConnectorError.new("Migration Workspace already exists. Please make sure to \
11
+ publish or discard any changes in the '#{workspace.id}' workspace.")
12
+ end
13
+ end
14
+
15
+ def write(workspace)
16
+ File.open(filename, 'w') do |file|
17
+ file.write(workspace.revision_id)
18
+ end
19
+ end
20
+
21
+ def remove
22
+ if exists?
23
+ File.delete(filename)
24
+ end
25
+ end
26
+
27
+ def exists?
28
+ File.exists?(filename)
29
+ end
30
+
31
+ private
32
+
33
+ def filename
34
+ File.join(Rails.root, 'tmp/migration_store.lock')
35
+ end
36
+ end
37
+ end
38
+ end
@@ -58,6 +58,18 @@ class Workspace
58
58
  self.id == 'published'
59
59
  end
60
60
 
61
+ def as_current(&block)
62
+ old_workspace = Workspace.current
63
+
64
+ begin
65
+ Workspace.current = self
66
+
67
+ yield
68
+ ensure
69
+ Workspace.current = old_workspace
70
+ end
71
+ end
72
+
61
73
  end
62
74
 
63
75
  end
@@ -0,0 +1,30 @@
1
+ namespace :cms do
2
+ desc 'Migrate the CMS'
3
+ task :migrate => :environment do
4
+ RailsConnector::Migrations::Migrator.new.migrate
5
+ end
6
+
7
+ namespace :migrate do
8
+ desc 'Publish the CMS migration workspace'
9
+ task :publish => :environment do
10
+ begin
11
+ RailsConnector::Migrations::Migrator.new.publish
12
+
13
+ puts 'Migration workspace published.'
14
+ rescue RailsConnector::RailsConnectorError => exception
15
+ puts exception.message
16
+ end
17
+ end
18
+
19
+ desc 'Delete the CMS migration workspace'
20
+ task :abort => :environment do
21
+ begin
22
+ RailsConnector::Migrations::Migrator.new.abort
23
+
24
+ puts 'Migration workspace deleted.'
25
+ rescue RailsConnector::RailsConnectorError => exception
26
+ puts exception.message
27
+ end
28
+ end
29
+ end
30
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: infopark_cloud_connector
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.8.1
4
+ version: 6.8.1.26.236500544
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-24 00:00:00.000000000 Z
12
+ date: 2013-01-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - '='
52
52
  - !ruby/object:Gem::Version
53
- version: 6.8.1
53
+ version: 6.8.1.26.236500544
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: 6.8.1
61
+ version: 6.8.1.26.236500544
62
62
  description: The Cloud Connector for Infopark CMS Fiona enables you to develop modern,
63
63
  dynamic Web 2.0 applications using Ruby on Rails and at the same time display CMS
64
64
  managed content.
@@ -73,6 +73,9 @@ files:
73
73
  - app/helpers/rails_connector/cms_tag_helper.rb
74
74
  - app/helpers/rails_connector/marker_helper.rb
75
75
  - config/routes.rb
76
+ - lib/generators/cms/migration/USAGE
77
+ - lib/generators/cms/migration/migration_generator.rb
78
+ - lib/generators/cms/migration/templates/migration.rb
76
79
  - lib/infopark_cloud_connector.rb
77
80
  - lib/rails_connector/access_denied.rb
78
81
  - lib/rails_connector/backend_not_available.rb
@@ -97,6 +100,14 @@ files:
97
100
  - lib/rails_connector/errors.rb
98
101
  - lib/rails_connector/link.rb
99
102
  - lib/rails_connector/log_subscriber.rb
103
+ - lib/rails_connector/migration.rb
104
+ - lib/rails_connector/migrations.rb
105
+ - lib/rails_connector/migrations/cms_backend.rb
106
+ - lib/rails_connector/migrations/migration.rb
107
+ - lib/rails_connector/migrations/migration_dsl.rb
108
+ - lib/rails_connector/migrations/migration_store.rb
109
+ - lib/rails_connector/migrations/migrator.rb
110
+ - lib/rails_connector/migrations/workspace_lock.rb
100
111
  - lib/rails_connector/named_link.rb
101
112
  - lib/rails_connector/obj.rb
102
113
  - lib/rails_connector/obj_data.rb
@@ -116,6 +127,7 @@ files:
116
127
  - lib/rails_connector/workspace_data_from_database.rb
117
128
  - lib/rails_connector/workspace_data_from_service.rb
118
129
  - lib/rails_connector/workspace_selection_middleware.rb
130
+ - lib/tasks/migration.rake
119
131
  homepage: http://www.infopark.de
120
132
  licenses: []
121
133
  post_install_message:
@@ -130,7 +142,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
130
142
  version: '0'
131
143
  segments:
132
144
  - 0
133
- hash: -881163793
145
+ hash: 620009807
134
146
  required_rubygems_version: !ruby/object:Gem::Requirement
135
147
  none: false
136
148
  requirements: