carton_db 1.1.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d16d6802fee28aa151d8eee4811d17d3a5dc00a5
4
- data.tar.gz: 22cb133e4202c80ef89109a24163c41b666ec89c
3
+ metadata.gz: b0569eb04a7231087ac8ba262cc56330a1c61912
4
+ data.tar.gz: aaae82f45cfdeb14e4dea5110e9a09c3b062ab5e
5
5
  SHA512:
6
- metadata.gz: 3ff1b4d0a6a5582d5903093e80051600e119f8c857b9ba32821081113b3cf90b3802c3f10f83a4fba0173b987ef55f699d3ae6289b1dfda47934b5105eb92b15
7
- data.tar.gz: 04747d51836cc9864fc5e5245f884d42c585cb434ba7ce66441f19836c87d841ed74a60765d5b93a5767f13279ae93b3c81da2b59ec853fbda5082961841472e
6
+ metadata.gz: e07e734b21b74e9988654549060f615897fb9b5e57763a61d392bf58ef0ff46845ba43118c805766f9177a117d0c4f7d49d1fa52e13e8e2042f410dd385b18a3
7
+ data.tar.gz: 5c818326762c092a868e9abc642ce1baa3a1b9a2fbe38a17c7932f0ebbbde99a1e0a8d72cd7479a98e61a5c97cc1516968f92e9c655cb0e1758333f02a778b2d
@@ -1,3 +1,6 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # frozen_string_literal: true
3
+
1
4
  require 'digest'
2
5
 
3
6
  module CartonDb
@@ -5,20 +8,22 @@ module CartonDb
5
8
  module Datum
6
9
 
7
10
  def self.for_plain(plain_text, auto_placeholder: false)
8
- return plain_text if plain_text.is_a?(Datum::Base)
9
- if auto_placeholder && plain_text.nil?
11
+ if auto_placeholder && (! plain_text) && plain_text.nil?
10
12
  Datum::Placeholder
13
+ elsif plain_text.is_a?(Datum::Base)
14
+ plain_text
11
15
  else
12
- Datum::ForPlain.new(plain_text)
16
+ Datum::ForPlain.new(plain_text.to_s)
13
17
  end
14
18
  end
15
19
 
16
20
  def self.for_escaped(escaped_text, auto_placeholder: false)
17
- return escaped_text if escaped_text.is_a?(Datum::Base)
18
- if auto_placeholder && escaped_text.nil?
21
+ if auto_placeholder && (! escaped_text) && escaped_text.nil?
19
22
  Datum::Placeholder
23
+ elsif escaped_text.is_a?(Datum::Base)
24
+ escaped_text
20
25
  else
21
- Datum::ForEscaped.new(escaped_text)
26
+ Datum::ForEscaped.new(escaped_text.to_s)
22
27
  end
23
28
  end
24
29
 
@@ -58,8 +63,9 @@ module CartonDb
58
63
  class ForPlain < Datum::Base
59
64
  attr_reader :plain
60
65
 
66
+
61
67
  def initialize(plain)
62
- if plain.nil?
68
+ if (! plain) && plain.nil?
63
69
  raise ArgumentError "A non-nil 'plain' value is required."
64
70
  end
65
71
  @plain = plain
@@ -90,7 +96,7 @@ module CartonDb
90
96
  attr_reader :escaped
91
97
 
92
98
  def initialize(escaped)
93
- if escaped.nil?
99
+ if (! escaped) && escaped.nil?
94
100
  raise ArgumentError "A non-nil 'escaped' value is required."
95
101
  end
96
102
  @escaped = escaped
@@ -1,42 +1,45 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # frozen_string_literal: true
3
+
1
4
  module CartonDb
2
5
 
3
6
  module Escaping
4
7
 
5
8
  ESCAPING_MAP = {
6
- "\u0000".freeze => '\x00'.freeze,
7
- "\u0001".freeze => '\x01'.freeze,
8
- "\u0002".freeze => '\x02'.freeze,
9
- "\u0003".freeze => '\x03'.freeze,
10
- "\u0004".freeze => '\x04'.freeze,
11
- "\u0005".freeze => '\x05'.freeze,
12
- "\u0006".freeze => '\x06'.freeze,
13
- "\u0007".freeze => '\a'.freeze,
14
- "\u0008".freeze => '\b'.freeze,
15
- "\u0009".freeze => '\t'.freeze,
16
- "\u000A".freeze => '\n'.freeze,
17
- "\u000B".freeze => '\v'.freeze,
18
- "\u000C".freeze => '\f'.freeze,
19
- "\u000D".freeze => '\r'.freeze,
20
- "\u000E".freeze => '\x0E'.freeze,
21
- "\u000F".freeze => '\x0F'.freeze,
22
- "\u0010".freeze => '\x10'.freeze,
23
- "\u0011".freeze => '\x11'.freeze,
24
- "\u0012".freeze => '\x12'.freeze,
25
- "\u0013".freeze => '\x13'.freeze,
26
- "\u0014".freeze => '\x14'.freeze,
27
- "\u0015".freeze => '\x15'.freeze,
28
- "\u0016".freeze => '\x16'.freeze,
29
- "\u0017".freeze => '\x17'.freeze,
30
- "\u0018".freeze => '\x18'.freeze,
31
- "\u0019".freeze => '\x19'.freeze,
32
- "\u001A".freeze => '\x1A'.freeze,
33
- "\u001B".freeze => '\x1B'.freeze,
34
- "\u001C".freeze => '\x1C'.freeze,
35
- "\u001D".freeze => '\x1D'.freeze,
36
- "\u001E".freeze => '\x1E'.freeze,
37
- "\u001F".freeze => '\x1F'.freeze,
38
- "\u007F".freeze => '\x7F'.freeze,
39
- "\\".freeze => "\\\\".freeze,
9
+ "\u0000" => '\x00',
10
+ "\u0001" => '\x01',
11
+ "\u0002" => '\x02',
12
+ "\u0003" => '\x03',
13
+ "\u0004" => '\x04',
14
+ "\u0005" => '\x05',
15
+ "\u0006" => '\x06',
16
+ "\u0007" => '\a',
17
+ "\u0008" => '\b',
18
+ "\u0009" => '\t',
19
+ "\u000A" => '\n',
20
+ "\u000B" => '\v',
21
+ "\u000C" => '\f',
22
+ "\u000D" => '\r',
23
+ "\u000E" => '\x0E',
24
+ "\u000F" => '\x0F',
25
+ "\u0010" => '\x10',
26
+ "\u0011" => '\x11',
27
+ "\u0012" => '\x12',
28
+ "\u0013" => '\x13',
29
+ "\u0014" => '\x14',
30
+ "\u0015" => '\x15',
31
+ "\u0016" => '\x16',
32
+ "\u0017" => '\x17',
33
+ "\u0018" => '\x18',
34
+ "\u0019" => '\x19',
35
+ "\u001A" => '\x1A',
36
+ "\u001B" => '\x1B',
37
+ "\u001C" => '\x1C',
38
+ "\u001D" => '\x1D',
39
+ "\u001E" => '\x1E',
40
+ "\u001F" => '\x1F',
41
+ "\u007F" => '\x7F',
42
+ "\\" => "\\\\",
40
43
  }.freeze
41
44
 
42
45
  UNESCAPING_MAP = ESCAPING_MAP.invert.freeze
@@ -1,5 +1,8 @@
1
1
  # -*- coding: UTF-8 -*-
2
+ # frozen_string_literal: true
3
+
2
4
  require 'fileutils'
5
+ require 'set'
3
6
 
4
7
  module CartonDb
5
8
  class ListMapDb
@@ -58,6 +61,55 @@ module CartonDb
58
61
  ! content?
59
62
  end
60
63
 
64
+ def key_count
65
+ return 0 if empty?
66
+ key_d_set.length
67
+ end
68
+
69
+ def touch_d(key_d, optimization)
70
+ if optimization == :small && content?
71
+ each_entry_element_line do |kd, _ed, _line|
72
+ return if kd == key_d
73
+ end
74
+ end
75
+
76
+ open_append do |io|
77
+ io << key_d.escaped << "\n"
78
+ end
79
+ end
80
+
81
+ def key_d_set
82
+ result = Set.new
83
+ each_entry_element_line do |kd, _ed, _line|
84
+ result << kd
85
+ end
86
+ result
87
+ end
88
+
89
+ def key_d?(key_d)
90
+ each_entry_element_line do |kd, _ed, _line|
91
+ return true if kd = key_d
92
+ end
93
+ false
94
+ end
95
+
96
+ def element_d?(key_d, element_d)
97
+ each_entry_element_line do |kd, ed, _line|
98
+ return true if kd == key_d && ed == element_d
99
+ end
100
+ false
101
+ end
102
+
103
+ def collect_content(key_d, collection_class)
104
+ result = nil
105
+ each_entry_element_line do |kd, ed, _line|
106
+ next unless kd == key_d
107
+ result ||= collection_class.new
108
+ result << ed.plain unless ed.placeholder?
109
+ end
110
+ result
111
+ end
112
+
61
113
  def each_entry
62
114
  entries = nil
63
115
  each_entry_element_line do |key_d, elem_d, _line|
@@ -71,6 +123,13 @@ module CartonDb
71
123
  end
72
124
  end
73
125
 
126
+ def each_element_for_d(key_d)
127
+ each_entry_element_line do |kd, ed, _line|
128
+ next unless kd == key_d
129
+ yield ed
130
+ end
131
+ end
132
+
74
133
  def each_first_element
75
134
  first_entries = nil
76
135
  each_entry_element_line do |key_d, elem_d, _line|
@@ -94,6 +153,41 @@ module CartonDb
94
153
  end
95
154
  end
96
155
 
156
+ def replace
157
+ replacement = self.class.new(
158
+ segment_group, "#{segment_filename}.txt"
159
+ )
160
+ begin
161
+ yield replacement
162
+ rescue StandardError
163
+ File.unlink replacement.filename
164
+ raise
165
+ end
166
+ File.unlink filename
167
+ File.rename replacement.filename, filename
168
+ end
169
+
170
+ def write_key_element_d(key_d, element_d)
171
+ open_append do |io|
172
+ io << "#{key_d.escaped}\t#{element_d.escaped}\n"
173
+ end
174
+ end
175
+
176
+ def write_key_d_elements(key_d, elements)
177
+ open_append do |io|
178
+ elements.each do |element|
179
+ element_d = CartonDb::Datum.for_plain(element)
180
+ io<< "#{key_d.escaped}\t#{element_d.escaped}\n"
181
+ end
182
+ end
183
+ end
184
+
185
+ def copy_entries_except(key_d, to_io)
186
+ each_entry_element_line do |kd, _ed, line|
187
+ to_io << line unless kd == key_d
188
+ end
189
+ end
190
+
97
191
  def open_append
98
192
  touch_dir
99
193
  File.open filename, 'a', **FILE_ENCODING_OPTS do |io|
@@ -1,4 +1,6 @@
1
1
  # -*- coding: UTF-8 -*-
2
+ # frozen_string_literal: true
3
+
2
4
  require 'fileutils'
3
5
 
4
6
  module CartonDb
@@ -1,4 +1,6 @@
1
1
  # -*- coding: UTF-8 -*-
2
+ # frozen_string_literal: true
3
+
2
4
  require 'forwardable'
3
5
  require 'fileutils'
4
6
  require 'carton_db/list_map_db/segment'
@@ -77,14 +79,7 @@ module CartonDb
77
79
  def [](key)
78
80
  key_d = CartonDb::Datum.for_plain(key)
79
81
  segment = segment_containing(key_d)
80
-
81
- ary = nil
82
- segment.each_entry_element_line do |kd, ed, _line|
83
- next ary unless kd == key_d
84
- ary ||= []
85
- ary << ed.plain unless ed.placeholder?
86
- end
87
- ary
82
+ segment.collect_content(key_d, Array)
88
83
  end
89
84
 
90
85
  # Returns true if an entry with the given key exists.
@@ -97,11 +92,7 @@ module CartonDb
97
92
  def key?(key)
98
93
  key_d = CartonDb::Datum.for_plain(key)
99
94
  segment = segment_containing(key_d)
100
-
101
- segment.each_entry_element_line do |kd, _ed, _line|
102
- return true if kd = key_d
103
- end
104
- false
95
+ segment.key_d?(key_d)
105
96
  end
106
97
 
107
98
  # Returns trus if an entry with the given key exists and its
@@ -116,11 +107,7 @@ module CartonDb
116
107
  key_d = CartonDb::Datum.for_plain(key)
117
108
  element_d = CartonDb::Datum.for_plain(element)
118
109
  segment = segment_containing(key_d)
119
-
120
- segment.each_entry_element_line do |kd, ed, _line|
121
- return true if kd == key_d && ed == element_d
122
- end
123
- false
110
+ segment.element_d?(key_d, element_d)
124
111
  end
125
112
 
126
113
  # Returns true if the map has no entries.
@@ -143,14 +130,8 @@ module CartonDb
143
130
  # @return [Fixnum]
144
131
  def count
145
132
  key_count = 0
146
- file_key_datum_set = Set.new
147
133
  ListMapDb::Segment.each_in_db name do |segment|
148
- next if segment.empty?
149
- file_key_datum_set.clear
150
- segment.each_entry_element_line do |kd, _ed, _line|
151
- file_key_datum_set << kd
152
- end
153
- key_count += file_key_datum_set.length
134
+ key_count += segment.key_count
154
135
  end
155
136
  key_count
156
137
  end
@@ -177,16 +158,7 @@ module CartonDb
177
158
 
178
159
  key_d = CartonDb::Datum.for_plain(key)
179
160
  segment = segment_containing(key_d)
180
-
181
- if optimization == :small && segment.content?
182
- segment.each_entry_element_line do |kd, _ed, _line|
183
- return if kd == key_d
184
- end
185
- end
186
-
187
- segment.open_append do |io|
188
- io << key_d.escaped << "\n"
189
- end
161
+ segment.touch_d key_d, optimization
190
162
  end
191
163
 
192
164
  # Removes all entries from the database, leaving it empty.
@@ -245,16 +217,11 @@ module CartonDb
245
217
  segment = segment_containing(key_d)
246
218
  return if segment.empty?
247
219
 
248
- new_segment = ListMapDb::Segment.new(
249
- segment.segment_group, "#{segment.segment_filename}.new")
250
- new_segment.open_overwrite do |io|
251
- segment.each_entry_element_line do |kd, _ed, line|
252
- io << line unless kd == key_d
220
+ segment.replace do |replacement|
221
+ replacement.open_overwrite do |repl_io|
222
+ segment.copy_entries_except key_d, repl_io
253
223
  end
254
224
  end
255
-
256
- File.unlink segment.filename
257
- File.rename new_segment.filename, segment.filename
258
225
  end
259
226
 
260
227
  # Appends an element string to the content of an entry.
@@ -272,10 +239,7 @@ module CartonDb
272
239
  key_d = CartonDb::Datum.for_plain(key)
273
240
  element_d = CartonDb::Datum.for_plain(element)
274
241
  segment = segment_containing(key_d)
275
- FileUtils.mkpath File.dirname(segment.filename)
276
- segment.open_append do |io|
277
- io << "#{key_d.escaped}\t#{element_d.escaped}\n"
278
- end
242
+ segment.write_key_element_d key_d, element_d
279
243
  end
280
244
 
281
245
  # Appends any number of element strings to the content of an
@@ -313,12 +277,7 @@ module CartonDb
313
277
  def concat_any_elements(key, elements)
314
278
  key_d = CartonDb::Datum.for_plain(key)
315
279
  segment = segment_containing(key_d)
316
- segment.open_append do |io|
317
- elements.each do |element|
318
- element_d = CartonDb::Datum.for_plain(element)
319
- io<< "#{key_d.escaped}\t#{element_d.escaped}\n"
320
- end
321
- end
280
+ segment.write_key_d_elements key_d, elements
322
281
  end
323
282
 
324
283
  # Appends an element to the content of an entry if no
@@ -353,8 +312,7 @@ module CartonDb
353
312
  CartonDb::Datum.for_plain(el)
354
313
  }
355
314
  segment = segment_containing(key_d)
356
- segment.each_entry_element_line do |kd, ed, _line|
357
- next unless kd == key_d
315
+ segment.each_element_for_d key_d do |ed|
358
316
  eds_idx = element_ds.index(ed)
359
317
  element_ds.delete_at(eds_idx) if eds_idx
360
318
  end
@@ -367,24 +325,14 @@ module CartonDb
367
325
  attr_accessor :name
368
326
 
369
327
  def replace_entry_in_file(segment, key_d, content)
370
- new_segment = ListMapDb::Segment.new(
371
- segment.segment_group, "#{segment.segment_filename}.new")
372
- new_segment.open_overwrite do |nf_io|
373
- segment.each_entry_element_line do |kd, _ed, line|
374
- nf_io.print line unless kd == key_d
375
- end
376
- element_count = 0
377
- content.each do |element|
378
- element_d = CartonDb::Datum.for_plain(element)
379
- element_count += 1
380
- nf_io.puts "#{key_d.escaped}\t#{element_d.escaped}"
381
- end
382
- if element_count.zero?
383
- nf_io.puts key_d.escaped
328
+ segment.replace do |replacement|
329
+ replacement.open_overwrite do |repl_io|
330
+ segment.copy_entries_except key_d, repl_io
331
+ element_count = 0
332
+ count = write_key_elements(key_d, content, repl_io)
333
+ repl_io << "#{key_d.escaped}\n" if count.zero?
384
334
  end
385
335
  end
386
- File.unlink segment.filename
387
- File.rename new_segment.filename, segment.filename
388
336
  end
389
337
 
390
338
  def segment_containing(key)
@@ -399,6 +347,16 @@ module CartonDb
399
347
  ! occupied
400
348
  end
401
349
 
350
+ def write_key_elements(key_d, elements, to_io)
351
+ count = 0
352
+ elements.each do |element|
353
+ element_d = CartonDb::Datum.for_plain(element)
354
+ count += 1
355
+ to_io << "#{key_d.escaped}\t#{element_d.escaped}\n"
356
+ end
357
+ count
358
+ end
359
+
402
360
  end
403
361
 
404
362
  end
@@ -1,3 +1,6 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # frozen_string_literal: true
3
+
1
4
  require 'set'
2
5
  require 'forwardable'
3
6
 
@@ -1,3 +1,6 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # frozen_string_literal: true
3
+
1
4
  require 'forwardable'
2
5
 
3
6
  module CartonDb
@@ -1,4 +1,6 @@
1
1
  # -*- coding: UTF-8 -*-
2
+ # frozen_string_literal: true
3
+
2
4
  module CartonDb
3
- VERSION = "1.1.2"
5
+ VERSION = "1.1.3"
4
6
  end
data/lib/carton_db.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  # -*- coding: UTF-8 -*-
2
+ # frozen_string_literal: true
3
+
2
4
  require "carton_db/version"
3
5
  require "carton_db/escaping"
4
6
  require "carton_db/datum"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: carton_db
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steve Jorgensen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-05-08 00:00:00.000000000 Z
11
+ date: 2017-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler