active_model_archive 0.0.3 → 0.0.4

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.
@@ -1,3 +1,3 @@
1
1
  module ActiveModelArchive
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
@@ -3,12 +3,71 @@ require 'active_support/concern'
3
3
 
4
4
  module ActiveModel
5
5
  module Archive
6
- extend ActiveSupport::Concern
7
-
8
6
  MAGIC = 42098
9
7
  CURRENT_VERSION = 1
10
8
  SUPPORTED_VERSIONS = [1]
11
9
 
10
+ class FileManager
11
+ UNLIMITED_PER_FILE = 999999999
12
+ attr_accessor :item_count, :file_number, :base_filename, :items_per_file
13
+ def initialize(base_filename, items_per_file)
14
+ @item_count = 0
15
+ @file_number = 0
16
+ @base_filename = base_filename
17
+ @items_per_file = (items_per_file.presence || UNLIMITED_PER_FILE).to_i
18
+ end
19
+
20
+ def add(object)
21
+ Rails.logger.info "Adding #{object.id}"
22
+
23
+ if item_count % items_per_file == 0
24
+ close_current_file
25
+ @current_file = create_file
26
+ end
27
+
28
+ self.item_count += 1
29
+
30
+ encoder.encode(object.as_archive, nil) do |json|
31
+ # write size, record, and crc
32
+ write_int(@current_file, json.bytesize)
33
+ @current_file.write(json)
34
+ write_int(@current_file, Zlib::crc32(json))
35
+ end
36
+ end
37
+
38
+ def create_file
39
+ self.file_number += 1
40
+
41
+ filename = items_per_file == UNLIMITED_PER_FILE ? base_filename : "#{base_filename}.#{file_number}"
42
+ file = File.open(filename, "w")
43
+ file.set_encoding("ASCII-8BIT")
44
+
45
+ write_int(file, MAGIC)
46
+ write_int(file, CURRENT_VERSION)
47
+
48
+ file
49
+ end
50
+
51
+ def close_current_file
52
+ if @current_file
53
+ write_int(@current_file, 0)
54
+ write_int(@current_file, item_count - ((file_number - 1) * items_per_file))
55
+ write_int(@current_file, MAGIC)
56
+
57
+ @current_file.close
58
+ end
59
+ end
60
+
61
+ def write_int(file, int)
62
+ file.write([int].pack("N"))
63
+ end
64
+
65
+ def encoder
66
+ @encoder ||= Yajl::Encoder.new
67
+ end
68
+ end
69
+
70
+ extend ActiveSupport::Concern
12
71
  # dump file format:
13
72
  # version 1:
14
73
  #
@@ -38,57 +97,42 @@ module ActiveModel
38
97
  # uses paginated_each with query params
39
98
  # executes the block with each dumped record if given
40
99
  # the block can be used to log progress
41
- def dump!(stream, query_params={}, &block)
42
- # set the encoding so we can write packed ints
43
- stream.set_encoding("ASCII-8BIT")
44
-
45
- archive_write_int(stream, MAGIC)
46
- archive_write_int(stream, CURRENT_VERSION)
100
+ def dump!(filename, options = {})
101
+ query = options[:query]
102
+ per_file = options[:per_file]
47
103
 
48
- count = 0
49
- encoder = Yajl::Encoder.new
104
+ file_manager = FileManager.new(filename, per_file)
50
105
 
51
- writer = lambda do |json|
52
- # write size, record, and crc
53
- archive_write_int(stream, json.bytesize)
54
- stream.write(json)
55
- archive_write_int(stream, Zlib::crc32(json))
56
- count += 1
57
- end
58
-
59
- if query_params.blank?
106
+ if query.blank?
60
107
  find_each do |object|
61
- encoder.encode(object.as_archive, nil, &writer)
62
- block.call(object) if block_given?
108
+ file_manager.add(object)
63
109
  end
64
110
  else
65
- paginated_each(query_params) do |object|
66
- encoder.encode(object.as_archive, nil, &writer)
67
- block.call(object) if block_given?
111
+ paginated_each(query) do |object|
112
+ file_manager.add(object)
68
113
  end
69
114
  end
70
115
 
71
- archive_write_int(stream, 0)
72
- archive_write_int(stream, count)
73
- archive_write_int(stream, MAGIC)
116
+ file_manager.close_current_file
117
+ file_manager.item_count
118
+ end
74
119
 
75
- stream.flush
76
- return count
120
+ def restore!(stream, options={})
121
+ each_instance do |object|
122
+ object.save(:validate => !!options[:validate])
123
+ yield object if block_given?
124
+ end
77
125
  end
78
126
 
79
- # Restore records from a stream.
80
- # require attributes= and save accepting :validate option
81
- # set :check true to only check the archive and not restore. if no exceptions are thrown, archive is valid.
82
- # set :validate true to validate records as they are saved
83
- # executes the block with each restored record if given
84
- # the block can be used to log progress and warn about invalid objects
85
- def restore!(stream, options={}, &block)
127
+ def each_instance(stream)
128
+ each_archive(stream) do |hash|
129
+ yield from_archive(hash)
130
+ end
131
+ end
86
132
 
87
- # for each hash read, create an object
133
+ def each_record(stream)
88
134
  each_archive(stream) do |hash|
89
- o = from_archive(hash)
90
- o.save(:validate => !!options[:validate])
91
- yield o if block_given?
135
+ yield find(hash['id'])
92
136
  end
93
137
  end
94
138
 
@@ -121,7 +165,7 @@ module ActiveModel
121
165
  raise "Unexpected end of archive file" unless magic == MAGIC
122
166
  raise "Record counts didn't match: #{record_count} in stream, #{count} read" unless record_count == count
123
167
 
124
- return count
168
+ count
125
169
  end
126
170
 
127
171
  # returns true if the archive is valid
@@ -147,10 +191,6 @@ module ActiveModel
147
191
  def archive_read_int(stream)
148
192
  stream.read(4).unpack("N").first
149
193
  end
150
-
151
- def archive_write_int(stream, int)
152
- stream.write([int].pack("N"))
153
- end
154
194
  end
155
195
 
156
196
  # instance method to return archived hash
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_model_archive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-03-25 00:00:00.000000000 -07:00
13
- default_executable:
12
+ date: 2011-07-27 00:00:00.000000000Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: activesupport
17
- requirement: &21767140 !ruby/object:Gem::Requirement
16
+ requirement: &2160497260 !ruby/object:Gem::Requirement
18
17
  none: false
19
18
  requirements:
20
19
  - - ~>
@@ -22,10 +21,10 @@ dependencies:
22
21
  version: '3'
23
22
  type: :runtime
24
23
  prerelease: false
25
- version_requirements: *21767140
24
+ version_requirements: *2160497260
26
25
  - !ruby/object:Gem::Dependency
27
26
  name: yajl-ruby
28
- requirement: &21766380 !ruby/object:Gem::Requirement
27
+ requirement: &2160496760 !ruby/object:Gem::Requirement
29
28
  none: false
30
29
  requirements:
31
30
  - - ! '>='
@@ -33,10 +32,10 @@ dependencies:
33
32
  version: '0'
34
33
  type: :runtime
35
34
  prerelease: false
36
- version_requirements: *21766380
35
+ version_requirements: *2160496760
37
36
  - !ruby/object:Gem::Dependency
38
37
  name: rspec
39
- requirement: &21765700 !ruby/object:Gem::Requirement
38
+ requirement: &2160496300 !ruby/object:Gem::Requirement
40
39
  none: false
41
40
  requirements:
42
41
  - - ~>
@@ -44,7 +43,7 @@ dependencies:
44
43
  version: '2'
45
44
  type: :development
46
45
  prerelease: false
47
- version_requirements: *21765700
46
+ version_requirements: *2160496300
48
47
  description: Adds dump and restore functionality to activemodel classes
49
48
  email:
50
49
  - grantr@gmail.com
@@ -61,7 +60,6 @@ files:
61
60
  - lib/active_model_archive/version.rb
62
61
  - spec/archive_spec.rb
63
62
  - spec/spec_helper.rb
64
- has_rdoc: true
65
63
  homepage: ''
66
64
  licenses: []
67
65
  post_install_message:
@@ -82,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
80
  version: '0'
83
81
  requirements: []
84
82
  rubyforge_project: active_model_archive
85
- rubygems_version: 1.6.2
83
+ rubygems_version: 1.8.5
86
84
  signing_key:
87
85
  specification_version: 3
88
86
  summary: Dump and restore activemodel objects