active_model_archive 0.0.3 → 0.0.4

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