offroad 0.0.2 → 0.0.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.
- data/LICENSE +674 -674
- data/README.rdoc +29 -29
- data/Rakefile +75 -75
- data/TODO +42 -42
- data/lib/app/models/offroad/group_state.rb +85 -85
- data/lib/app/models/offroad/mirror_info.rb +53 -53
- data/lib/app/models/offroad/model_state.rb +36 -36
- data/lib/app/models/offroad/received_record_state.rb +115 -115
- data/lib/app/models/offroad/sendable_record_state.rb +91 -91
- data/lib/app/models/offroad/system_state.rb +33 -33
- data/lib/cargo_streamer.rb +222 -222
- data/lib/controller_extensions.rb +74 -74
- data/lib/exceptions.rb +16 -16
- data/lib/migrate/20100512164608_create_offroad_tables.rb +72 -72
- data/lib/mirror_data.rb +376 -376
- data/lib/model_extensions.rb +378 -377
- data/lib/module_funcs.rb +94 -94
- data/lib/offroad.rb +41 -41
- data/lib/version.rb +3 -3
- data/lib/view_helper.rb +7 -7
- data/templates/offline.rb +36 -36
- data/templates/offline_database.yml +7 -7
- data/templates/offroad.yml +6 -6
- data/test/app_root/app/controllers/application_controller.rb +2 -2
- data/test/app_root/app/controllers/group_controller.rb +28 -28
- data/test/app_root/app/models/global_record.rb +10 -10
- data/test/app_root/app/models/group.rb +12 -12
- data/test/app_root/app/models/group_owned_record.rb +68 -68
- data/test/app_root/app/models/guest.rb +7 -7
- data/test/app_root/app/models/subrecord.rb +12 -12
- data/test/app_root/app/models/unmirrored_record.rb +4 -4
- data/test/app_root/app/views/group/download_down_mirror.html.erb +3 -3
- data/test/app_root/app/views/group/download_initial_down_mirror.html.erb +3 -3
- data/test/app_root/app/views/group/download_up_mirror.html.erb +5 -5
- data/test/app_root/app/views/layouts/mirror.html.erb +8 -8
- data/test/app_root/config/boot.rb +115 -115
- data/test/app_root/config/database-pg.yml +8 -8
- data/test/app_root/config/database.yml +5 -5
- data/test/app_root/config/environment.rb +24 -24
- data/test/app_root/config/environments/test.rb +17 -17
- data/test/app_root/config/offroad.yml +6 -6
- data/test/app_root/config/routes.rb +4 -4
- data/test/app_root/db/migrate/20100529235049_create_tables.rb +64 -64
- data/test/app_root/lib/common_hobo.rb +15 -15
- data/test/app_root/vendor/plugins/offroad/init.rb +2 -2
- data/test/functional/mirror_operations_test.rb +148 -148
- data/test/test_helper.rb +453 -453
- data/test/unit/app_state_tracking_test.rb +275 -275
- data/test/unit/cargo_streamer_test.rb +332 -332
- data/test/unit/global_data_test.rb +102 -102
- data/test/unit/group_controller_test.rb +152 -152
- data/test/unit/group_data_test.rb +442 -435
- data/test/unit/group_single_test.rb +136 -136
- data/test/unit/hobo_permissions_test.rb +57 -57
- data/test/unit/mirror_data_test.rb +1283 -1283
- data/test/unit/mirror_info_test.rb +31 -31
- data/test/unit/module_funcs_test.rb +37 -37
- data/test/unit/pathological_model_test.rb +62 -62
- data/test/unit/test_framework_test.rb +86 -86
- data/test/unit/unmirrored_data_test.rb +14 -14
- metadata +6 -8
data/README.rdoc
CHANGED
@@ -1,29 +1,29 @@
|
|
1
|
-
*NOTE*: This gem is a work in progress. It does work, but it's not especially convenient, yet.
|
2
|
-
Better documentation and scripts will follow in time.
|
3
|
-
|
4
|
-
*NOTE*: Currently the gem is only compatible with Rails 2.
|
5
|
-
|
6
|
-
== Overview
|
7
|
-
|
8
|
-
This gem allows users without Internet access to still use your app. It requires that your application can
|
9
|
-
be thought of in the following way:
|
10
|
-
|
11
|
-
Your site is broken down into a set of "groups" or "organizations". Each group has their own distinct set of
|
12
|
-
records, which are editable by only a distinct set of a users. Besides that, there are global records that can
|
13
|
-
only be edited by overall site administrators, though they can possibly be viewed by regular users.
|
14
|
-
|
15
|
-
In order to make offline use of your app possible, Offroad will generate an installer bundle, which is an
|
16
|
-
OS-specific executable that can install Ruby, Rails, and also a launcher which controls a local instance of
|
17
|
-
WEBrick and manages imports and exports. The installer and launcher will be visually labelled everywhere with
|
18
|
-
the name of the Rails app itself, making its function obvious to users. This launcher can generate up-mirror
|
19
|
-
files, which are transported on a USB thumbdrive or some other medium to an online system, where they can be
|
20
|
-
uploaded to the main app site. After having done an upload, the user is prompted to download a down-mirror
|
21
|
-
file which contains any changes to the global records, and bring this back to the offline system, which
|
22
|
-
completes the sneakernet round-trip.
|
23
|
-
|
24
|
-
Rather than sending all data, only globally accessible records and updates to the app itself are transferred
|
25
|
-
in the down-mirror (except for the first down-mirror, which also contains the initial set of records for the
|
26
|
-
group). Furthermore, the offline version of the app is considered be the absolutely canonical source of that
|
27
|
-
group's records; really, this is not a "sync", it's a "mirror". This means that no-one on the online site can
|
28
|
-
make changes to an offline group's records, not even the administrator; this is enforced by Offroad at a
|
29
|
-
low level.
|
1
|
+
*NOTE*: This gem is a work in progress. It does work, but it's not especially convenient, yet.
|
2
|
+
Better documentation and scripts will follow in time.
|
3
|
+
|
4
|
+
*NOTE*: Currently the gem is only compatible with Rails 2.
|
5
|
+
|
6
|
+
== Overview
|
7
|
+
|
8
|
+
This gem allows users without Internet access to still use your app. It requires that your application can
|
9
|
+
be thought of in the following way:
|
10
|
+
|
11
|
+
Your site is broken down into a set of "groups" or "organizations". Each group has their own distinct set of
|
12
|
+
records, which are editable by only a distinct set of a users. Besides that, there are global records that can
|
13
|
+
only be edited by overall site administrators, though they can possibly be viewed by regular users.
|
14
|
+
|
15
|
+
In order to make offline use of your app possible, Offroad will generate an installer bundle, which is an
|
16
|
+
OS-specific executable that can install Ruby, Rails, and also a launcher which controls a local instance of
|
17
|
+
WEBrick and manages imports and exports. The installer and launcher will be visually labelled everywhere with
|
18
|
+
the name of the Rails app itself, making its function obvious to users. This launcher can generate up-mirror
|
19
|
+
files, which are transported on a USB thumbdrive or some other medium to an online system, where they can be
|
20
|
+
uploaded to the main app site. After having done an upload, the user is prompted to download a down-mirror
|
21
|
+
file which contains any changes to the global records, and bring this back to the offline system, which
|
22
|
+
completes the sneakernet round-trip.
|
23
|
+
|
24
|
+
Rather than sending all data, only globally accessible records and updates to the app itself are transferred
|
25
|
+
in the down-mirror (except for the first down-mirror, which also contains the initial set of records for the
|
26
|
+
group). Furthermore, the offline version of the app is considered be the absolutely canonical source of that
|
27
|
+
group's records; really, this is not a "sync", it's a "mirror". This means that no-one on the online site can
|
28
|
+
make changes to an offline group's records, not even the administrator; this is enforced by Offroad at a
|
29
|
+
low level.
|
data/Rakefile
CHANGED
@@ -1,75 +1,75 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rake'
|
3
|
-
require 'rake/testtask'
|
4
|
-
require 'rake/rdoctask'
|
5
|
-
require 'rake/gempackagetask'
|
6
|
-
|
7
|
-
def common_test_settings(t)
|
8
|
-
t.libs << 'lib'
|
9
|
-
t.libs << 'test'
|
10
|
-
t.pattern = 'test/**/*_test.rb'
|
11
|
-
t.verbose = true
|
12
|
-
end
|
13
|
-
|
14
|
-
desc 'Default: run unit and functional tests.'
|
15
|
-
task :default => :test
|
16
|
-
|
17
|
-
desc 'Test Offroad'
|
18
|
-
Rake::TestTask.new(:test) do |t|
|
19
|
-
common_test_settings(t)
|
20
|
-
end
|
21
|
-
|
22
|
-
desc 'Generate documentation for Offroad.'
|
23
|
-
Rake::RDocTask.new(:rdoc) do |rdoc|
|
24
|
-
rdoc.rdoc_dir = 'rdoc'
|
25
|
-
rdoc.title = 'Offroad'
|
26
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
27
|
-
rdoc.rdoc_files.include('README')
|
28
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
29
|
-
end
|
30
|
-
|
31
|
-
begin
|
32
|
-
require 'rcov/rcovtask'
|
33
|
-
|
34
|
-
Rcov::RcovTask.new(:rcov) do |t|
|
35
|
-
common_test_settings(t)
|
36
|
-
t.pattern = 'test/unit/*_test.rb' # Don't care about coverage added by functional tests
|
37
|
-
t.rcov_opts << '-o coverage -x "/ruby/,/gems/,/test/,/migrate/"'
|
38
|
-
end
|
39
|
-
rescue LoadError
|
40
|
-
# Rcov wasn't available
|
41
|
-
end
|
42
|
-
|
43
|
-
begin
|
44
|
-
require 'ruby-prof/task'
|
45
|
-
|
46
|
-
RubyProf::ProfileTask.new(:profile) do |t|
|
47
|
-
common_test_settings(t)
|
48
|
-
t.output_dir = "#{File.dirname(__FILE__)}/profile"
|
49
|
-
t.printer = :call_tree
|
50
|
-
t.min_percent = 10
|
51
|
-
end
|
52
|
-
rescue LoadError
|
53
|
-
# Ruby-prof wasn't available
|
54
|
-
end
|
55
|
-
|
56
|
-
require 'lib/version'
|
57
|
-
gemspec = Gem::Specification.new do |s|
|
58
|
-
s.name = "offroad"
|
59
|
-
s.version = Offroad::VERSION
|
60
|
-
s.authors = ["David Mike Simon"]
|
61
|
-
s.email = "david.mike.simon@gmail.com"
|
62
|
-
s.homepage = "http://github.com/DavidMikeSimon/offroad"
|
63
|
-
s.summary = "Manages off-Internet instances of a Rails app"
|
64
|
-
s.description = "Offroad manages offline instances of a Rails app on computers without Internet access. The online and offline instances can communicate via mirror files, transported by the user via thumbdrive, burned CD, etc."
|
65
|
-
|
66
|
-
s.files = `git ls-files .`.split("\n") - [".gitignore"]
|
67
|
-
s.platform = Gem::Platform::RUBY
|
68
|
-
s.require_path = 'lib'
|
69
|
-
s.rubyforge_project = '[none]'
|
70
|
-
|
71
|
-
s.add_dependency('ar-extensions', '0.9.4')
|
72
|
-
end
|
73
|
-
|
74
|
-
Rake::GemPackageTask.new(gemspec) do |pkg|
|
75
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rake/rdoctask'
|
5
|
+
require 'rake/gempackagetask'
|
6
|
+
|
7
|
+
def common_test_settings(t)
|
8
|
+
t.libs << 'lib'
|
9
|
+
t.libs << 'test'
|
10
|
+
t.pattern = 'test/**/*_test.rb'
|
11
|
+
t.verbose = true
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Default: run unit and functional tests.'
|
15
|
+
task :default => :test
|
16
|
+
|
17
|
+
desc 'Test Offroad'
|
18
|
+
Rake::TestTask.new(:test) do |t|
|
19
|
+
common_test_settings(t)
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Generate documentation for Offroad.'
|
23
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
24
|
+
rdoc.rdoc_dir = 'rdoc'
|
25
|
+
rdoc.title = 'Offroad'
|
26
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
27
|
+
rdoc.rdoc_files.include('README')
|
28
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
29
|
+
end
|
30
|
+
|
31
|
+
begin
|
32
|
+
require 'rcov/rcovtask'
|
33
|
+
|
34
|
+
Rcov::RcovTask.new(:rcov) do |t|
|
35
|
+
common_test_settings(t)
|
36
|
+
t.pattern = 'test/unit/*_test.rb' # Don't care about coverage added by functional tests
|
37
|
+
t.rcov_opts << '-o coverage -x "/ruby/,/gems/,/test/,/migrate/"'
|
38
|
+
end
|
39
|
+
rescue LoadError
|
40
|
+
# Rcov wasn't available
|
41
|
+
end
|
42
|
+
|
43
|
+
begin
|
44
|
+
require 'ruby-prof/task'
|
45
|
+
|
46
|
+
RubyProf::ProfileTask.new(:profile) do |t|
|
47
|
+
common_test_settings(t)
|
48
|
+
t.output_dir = "#{File.dirname(__FILE__)}/profile"
|
49
|
+
t.printer = :call_tree
|
50
|
+
t.min_percent = 10
|
51
|
+
end
|
52
|
+
rescue LoadError
|
53
|
+
# Ruby-prof wasn't available
|
54
|
+
end
|
55
|
+
|
56
|
+
require 'lib/version'
|
57
|
+
gemspec = Gem::Specification.new do |s|
|
58
|
+
s.name = "offroad"
|
59
|
+
s.version = Offroad::VERSION
|
60
|
+
s.authors = ["David Mike Simon"]
|
61
|
+
s.email = "david.mike.simon@gmail.com"
|
62
|
+
s.homepage = "http://github.com/DavidMikeSimon/offroad"
|
63
|
+
s.summary = "Manages off-Internet instances of a Rails app"
|
64
|
+
s.description = "Offroad manages offline instances of a Rails app on computers without Internet access. The online and offline instances can communicate via mirror files, transported by the user via thumbdrive, burned CD, etc."
|
65
|
+
|
66
|
+
s.files = `git ls-files .`.split("\n") - [".gitignore"]
|
67
|
+
s.platform = Gem::Platform::RUBY
|
68
|
+
s.require_path = 'lib'
|
69
|
+
s.rubyforge_project = '[none]'
|
70
|
+
|
71
|
+
s.add_dependency('ar-extensions', '0.9.4')
|
72
|
+
end
|
73
|
+
|
74
|
+
Rake::GemPackageTask.new(gemspec) do |pkg|
|
75
|
+
end
|
data/TODO
CHANGED
@@ -1,42 +1,42 @@
|
|
1
|
-
High priority:
|
2
|
-
- Creating/updating the installer (ideally, git pull on target platform, one rake task, then git push)
|
3
|
-
- Add a generate task to initialize config files in a Rails app
|
4
|
-
- Documentation
|
5
|
-
- Resolve issue of too-long index names
|
6
|
-
|
7
|
-
Low priority:
|
8
|
-
- Make unit tests against bugs fixed by 7f8415 and 31455d
|
9
|
-
- Try to come up with some more convenient way of building unit-test-specific model classes
|
10
|
-
- Make sure ModelStates don't continue to stick around and cause trouble even after a class no longer acts_as_offroadable
|
11
|
-
- Get README into the auto-generated gem rdocs
|
12
|
-
- Get the test suite to stop generating a log file, it's annoying
|
13
|
-
- Use finer-grained exceptions to allow for better error testing
|
14
|
-
- Don't allow group_single records to reference non-single group records, since group_single "ownership" can change
|
15
|
-
- Don't assume "id" as primary key name, always look it up with the appropriate ActiveRecord method
|
16
|
-
- Allow offline app to relinquish ownership by setting a belongs_to field to 0 or NULL
|
17
|
-
- Figure out why Hobo assumes all fields non-editable (something I'm doing in the patched-in updatable check...)
|
18
|
-
- Assign a random number to group state when it is created, only accept mirror files with matching random number
|
19
|
-
- This is to prevent confusion if a group is made offline, then online, then offline again
|
20
|
-
- Also assign a random number to the online app, and only accept mirror files which match this number as well
|
21
|
-
- Prevents multiple installations of an app from reading each others' mirror files
|
22
|
-
- Use read transactions for mirror write operations (is it already doing this?)
|
23
|
-
- The launcher should keep a log file
|
24
|
-
- Include recent log lines (for both Rails and the launcher) in generated up-mirror files, for debugging purposes
|
25
|
-
- Use rails logger to note activity
|
26
|
-
- When mirror data version is confirmed, delete all sendable record state entries for deletions older than min(version) over all group_states
|
27
|
-
- Try to gather some kind of machine identifier to put in a offline-owned group_state column
|
28
|
-
- Try streaming out with large data sets and make sure it is sufficiently speedy, and is actually streaming (i.e. no Content-Length header)
|
29
|
-
- Change mime-type of mirror files being downloaded to something that doesn't allow it to be accidentally viewed in-browser
|
30
|
-
- Use md5sum on the entire cargo file instead of just each individual part, to protect against corruption outside the actual data segments
|
31
|
-
- Allow app to optionally specify batch sizes on a model-by-model basis
|
32
|
-
- Mirror file imports in the down mirror app should happen through GUI, and GUI should delete files once succesfully imported
|
33
|
-
- If offline app attempts to import a down mirror file and it doesn't work, it should:
|
34
|
-
- Delete the down mirror file as usual, but...
|
35
|
-
- Explain that it wasn't imported and that another down mirror file should be downloaded
|
36
|
-
- Figure out which activerecord methods skip the save callbacks, and wrap them to also update the mirror version
|
37
|
-
- Maybe methods for which this isn't practical should raise an error when called...
|
38
|
-
- Load all the other informational values in GroupState
|
39
|
-
- App creates a record then deletes it then sends mirror; does a deletion srs still get sent?
|
40
|
-
- For any fix to this: make sure that if app updates record then deletes it then sends mirror that deletion gets sent
|
41
|
-
- Maybe that means we need both create_version and update_version on srs?
|
42
|
-
- Put the CargoStreamer into its own gem, it might be handy for other stuff
|
1
|
+
High priority:
|
2
|
+
- Creating/updating the installer (ideally, git pull on target platform, one rake task, then git push)
|
3
|
+
- Add a generate task to initialize config files in a Rails app
|
4
|
+
- Documentation
|
5
|
+
- Resolve issue of too-long index names
|
6
|
+
|
7
|
+
Low priority:
|
8
|
+
- Make unit tests against bugs fixed by 7f8415 and 31455d
|
9
|
+
- Try to come up with some more convenient way of building unit-test-specific model classes
|
10
|
+
- Make sure ModelStates don't continue to stick around and cause trouble even after a class no longer acts_as_offroadable
|
11
|
+
- Get README into the auto-generated gem rdocs
|
12
|
+
- Get the test suite to stop generating a log file, it's annoying
|
13
|
+
- Use finer-grained exceptions to allow for better error testing
|
14
|
+
- Don't allow group_single records to reference non-single group records, since group_single "ownership" can change
|
15
|
+
- Don't assume "id" as primary key name, always look it up with the appropriate ActiveRecord method
|
16
|
+
- Allow offline app to relinquish ownership by setting a belongs_to field to 0 or NULL
|
17
|
+
- Figure out why Hobo assumes all fields non-editable (something I'm doing in the patched-in updatable check...)
|
18
|
+
- Assign a random number to group state when it is created, only accept mirror files with matching random number
|
19
|
+
- This is to prevent confusion if a group is made offline, then online, then offline again
|
20
|
+
- Also assign a random number to the online app, and only accept mirror files which match this number as well
|
21
|
+
- Prevents multiple installations of an app from reading each others' mirror files
|
22
|
+
- Use read transactions for mirror write operations (is it already doing this?)
|
23
|
+
- The launcher should keep a log file
|
24
|
+
- Include recent log lines (for both Rails and the launcher) in generated up-mirror files, for debugging purposes
|
25
|
+
- Use rails logger to note activity
|
26
|
+
- When mirror data version is confirmed, delete all sendable record state entries for deletions older than min(version) over all group_states
|
27
|
+
- Try to gather some kind of machine identifier to put in a offline-owned group_state column
|
28
|
+
- Try streaming out with large data sets and make sure it is sufficiently speedy, and is actually streaming (i.e. no Content-Length header)
|
29
|
+
- Change mime-type of mirror files being downloaded to something that doesn't allow it to be accidentally viewed in-browser
|
30
|
+
- Use md5sum on the entire cargo file instead of just each individual part, to protect against corruption outside the actual data segments
|
31
|
+
- Allow app to optionally specify batch sizes on a model-by-model basis
|
32
|
+
- Mirror file imports in the down mirror app should happen through GUI, and GUI should delete files once succesfully imported
|
33
|
+
- If offline app attempts to import a down mirror file and it doesn't work, it should:
|
34
|
+
- Delete the down mirror file as usual, but...
|
35
|
+
- Explain that it wasn't imported and that another down mirror file should be downloaded
|
36
|
+
- Figure out which activerecord methods skip the save callbacks, and wrap them to also update the mirror version
|
37
|
+
- Maybe methods for which this isn't practical should raise an error when called...
|
38
|
+
- Load all the other informational values in GroupState
|
39
|
+
- App creates a record then deletes it then sends mirror; does a deletion srs still get sent?
|
40
|
+
- For any fix to this: make sure that if app updates record then deletes it then sends mirror that deletion gets sent
|
41
|
+
- Maybe that means we need both create_version and update_version on srs?
|
42
|
+
- Put the CargoStreamer into its own gem, it might be handy for other stuff
|
@@ -1,85 +1,85 @@
|
|
1
|
-
module Offroad
|
2
|
-
private
|
3
|
-
|
4
|
-
class GroupState < ActiveRecord::Base
|
5
|
-
set_table_name "offroad_group_states"
|
6
|
-
|
7
|
-
validates_presence_of :app_group_id
|
8
|
-
|
9
|
-
def validate
|
10
|
-
errors.add_to_base "Cannot find associated app group record" unless app_group
|
11
|
-
end
|
12
|
-
|
13
|
-
def app_group
|
14
|
-
Offroad::group_base_model.find_by_id(app_group_id)
|
15
|
-
end
|
16
|
-
|
17
|
-
has_many :received_record_states, :class_name => "::Offroad::ReceivedRecordState", :dependent => :delete_all
|
18
|
-
|
19
|
-
named_scope :for_group, lambda { |group| { :conditions => {
|
20
|
-
:app_group_id => valid_group_record?(group) ? group.id : 0
|
21
|
-
} } }
|
22
|
-
|
23
|
-
def before_create
|
24
|
-
if Offroad::app_offline?
|
25
|
-
# FIXME : Fill in last_installation_at, launcher_version, app_version, etc
|
26
|
-
self.operating_system ||= RUBY_PLATFORM
|
27
|
-
end
|
28
|
-
|
29
|
-
self.confirmed_group_data_version ||= 1
|
30
|
-
|
31
|
-
# When first setting a group offline at online app, assume it will start out with at least current global data.
|
32
|
-
# It should, since that's the earliest version that could be loaded into the initial down mirror file.
|
33
|
-
self.confirmed_global_data_version ||= Offroad::app_online? ? SystemState::current_mirror_version : 1
|
34
|
-
end
|
35
|
-
|
36
|
-
def update_from_remote_group_state!(remote_gs)
|
37
|
-
versioning_columns = [
|
38
|
-
'confirmed_global_data_version',
|
39
|
-
'confirmed_group_data_version'
|
40
|
-
]
|
41
|
-
|
42
|
-
online_owned_columns = [
|
43
|
-
'last_installer_downloaded_at',
|
44
|
-
'last_down_mirror_created_at',
|
45
|
-
'last_up_mirror_loaded_at'
|
46
|
-
]
|
47
|
-
|
48
|
-
offline_owned_columns = [
|
49
|
-
'last_installation_at',
|
50
|
-
'last_down_mirror_loaded_at',
|
51
|
-
'last_up_mirror_created_at',
|
52
|
-
'launcher_version',
|
53
|
-
'app_version',
|
54
|
-
'operating_system'
|
55
|
-
]
|
56
|
-
|
57
|
-
# Copy in values from columns owned by the remote environment that created remote_gs
|
58
|
-
(Offroad::app_offline? ? online_owned_columns : offline_owned_columns).each do |col|
|
59
|
-
self.send("#{col}=", remote_gs.send(col))
|
60
|
-
end
|
61
|
-
|
62
|
-
# If the remote side says they have a newer version of something than we currently think they have, update
|
63
|
-
versioning_columns.each do |col|
|
64
|
-
self.send("#{col}=", [self.send(col), remote_gs.send(col)].max)
|
65
|
-
end
|
66
|
-
|
67
|
-
save!
|
68
|
-
end
|
69
|
-
|
70
|
-
def self.safe_to_load_from_cargo_stream?
|
71
|
-
true
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.note_group_destroyed(group)
|
75
|
-
rec = find_by_app_group_id(group.id)
|
76
|
-
rec.destroy
|
77
|
-
end
|
78
|
-
|
79
|
-
private
|
80
|
-
|
81
|
-
def self.valid_group_record?(rec)
|
82
|
-
rec.class.respond_to?(:offroad_group_base?) && rec.class.offroad_group_base?
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
1
|
+
module Offroad
|
2
|
+
private
|
3
|
+
|
4
|
+
class GroupState < ActiveRecord::Base
|
5
|
+
set_table_name "offroad_group_states"
|
6
|
+
|
7
|
+
validates_presence_of :app_group_id
|
8
|
+
|
9
|
+
def validate
|
10
|
+
errors.add_to_base "Cannot find associated app group record" unless app_group
|
11
|
+
end
|
12
|
+
|
13
|
+
def app_group
|
14
|
+
Offroad::group_base_model.find_by_id(app_group_id)
|
15
|
+
end
|
16
|
+
|
17
|
+
has_many :received_record_states, :class_name => "::Offroad::ReceivedRecordState", :dependent => :delete_all
|
18
|
+
|
19
|
+
named_scope :for_group, lambda { |group| { :conditions => {
|
20
|
+
:app_group_id => valid_group_record?(group) ? group.id : 0
|
21
|
+
} } }
|
22
|
+
|
23
|
+
def before_create
|
24
|
+
if Offroad::app_offline?
|
25
|
+
# FIXME : Fill in last_installation_at, launcher_version, app_version, etc
|
26
|
+
self.operating_system ||= RUBY_PLATFORM
|
27
|
+
end
|
28
|
+
|
29
|
+
self.confirmed_group_data_version ||= 1
|
30
|
+
|
31
|
+
# When first setting a group offline at online app, assume it will start out with at least current global data.
|
32
|
+
# It should, since that's the earliest version that could be loaded into the initial down mirror file.
|
33
|
+
self.confirmed_global_data_version ||= Offroad::app_online? ? SystemState::current_mirror_version : 1
|
34
|
+
end
|
35
|
+
|
36
|
+
def update_from_remote_group_state!(remote_gs)
|
37
|
+
versioning_columns = [
|
38
|
+
'confirmed_global_data_version',
|
39
|
+
'confirmed_group_data_version'
|
40
|
+
]
|
41
|
+
|
42
|
+
online_owned_columns = [
|
43
|
+
'last_installer_downloaded_at',
|
44
|
+
'last_down_mirror_created_at',
|
45
|
+
'last_up_mirror_loaded_at'
|
46
|
+
]
|
47
|
+
|
48
|
+
offline_owned_columns = [
|
49
|
+
'last_installation_at',
|
50
|
+
'last_down_mirror_loaded_at',
|
51
|
+
'last_up_mirror_created_at',
|
52
|
+
'launcher_version',
|
53
|
+
'app_version',
|
54
|
+
'operating_system'
|
55
|
+
]
|
56
|
+
|
57
|
+
# Copy in values from columns owned by the remote environment that created remote_gs
|
58
|
+
(Offroad::app_offline? ? online_owned_columns : offline_owned_columns).each do |col|
|
59
|
+
self.send("#{col}=", remote_gs.send(col))
|
60
|
+
end
|
61
|
+
|
62
|
+
# If the remote side says they have a newer version of something than we currently think they have, update
|
63
|
+
versioning_columns.each do |col|
|
64
|
+
self.send("#{col}=", [self.send(col), remote_gs.send(col)].max)
|
65
|
+
end
|
66
|
+
|
67
|
+
save!
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.safe_to_load_from_cargo_stream?
|
71
|
+
true
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.note_group_destroyed(group)
|
75
|
+
rec = find_by_app_group_id(group.id)
|
76
|
+
rec.destroy
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def self.valid_group_record?(rec)
|
82
|
+
rec.class.respond_to?(:offroad_group_base?) && rec.class.offroad_group_base?
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|