rroonga 2.1.2 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -113,7 +113,6 @@ rb_grn_object_run_finalizer (grn_ctx *context, grn_obj *grn_object,
113
113
  case GRN_CURSOR_TABLE_PAT_KEY:
114
114
  case GRN_CURSOR_TABLE_DAT_KEY:
115
115
  case GRN_CURSOR_TABLE_NO_KEY:
116
- case GRN_CURSOR_TABLE_VIEW:
117
116
  break;
118
117
  case GRN_TABLE_HASH_KEY:
119
118
  case GRN_TABLE_PAT_KEY:
@@ -122,7 +121,6 @@ rb_grn_object_run_finalizer (grn_ctx *context, grn_obj *grn_object,
122
121
  RB_GRN_TABLE_KEY_SUPPORT(rb_grn_object));
123
122
  break;
124
123
  case GRN_TABLE_NO_KEY:
125
- case GRN_TABLE_VIEW:
126
124
  rb_grn_table_finalizer(context, grn_object,
127
125
  RB_GRN_TABLE(rb_grn_object));
128
126
  break;
@@ -238,18 +236,12 @@ rb_grn_object_to_ruby_class (grn_obj *object)
238
236
  case GRN_TABLE_NO_KEY:
239
237
  klass = rb_cGrnArray;
240
238
  break;
241
- case GRN_TABLE_VIEW:
242
- klass = rb_cGrnView;
243
- break;
244
239
  case GRN_TYPE:
245
240
  klass = rb_cGrnType;
246
241
  break;
247
242
  case GRN_ACCESSOR:
248
243
  klass = rb_cGrnAccessor;
249
244
  break;
250
- case GRN_ACCESSOR_VIEW:
251
- klass = rb_cGrnViewAccessor;
252
- break;
253
245
  case GRN_SNIP:
254
246
  klass = rb_cGrnSnippet;
255
247
  break;
@@ -280,9 +272,6 @@ rb_grn_object_to_ruby_class (grn_obj *object)
280
272
  case GRN_CURSOR_TABLE_NO_KEY:
281
273
  klass = rb_cGrnArrayCursor;
282
274
  break;
283
- case GRN_CURSOR_TABLE_VIEW:
284
- klass = rb_cGrnViewCursor;
285
- break;
286
275
  default:
287
276
  rb_raise(rb_eTypeError,
288
277
  "unsupported groonga object type for class detection: 0x%x",
@@ -416,7 +405,6 @@ rb_grn_object_assign (VALUE klass, VALUE self, VALUE rb_context,
416
405
  klass == rb_cGrnPatriciaTrieCursor ||
417
406
  klass == rb_cGrnDoubleArrayTrieCursor ||
418
407
  klass == rb_cGrnArrayCursor ||
419
- klass == rb_cGrnViewCursor ||
420
408
  klass == rb_cGrnIndexCursor ||
421
409
  klass == rb_cGrnProcedure ||
422
410
  klass == rb_cGrnVariable) {
@@ -450,12 +438,6 @@ rb_grn_object_assign (VALUE klass, VALUE self, VALUE rb_context,
450
438
  rb_grn_object_bind_common(klass, self, rb_context, rb_grn_object,
451
439
  context, object);
452
440
  rb_grn_accessor_bind(RB_GRN_ACCESSOR(rb_grn_object), context, object);
453
- } else if (klass == rb_cGrnViewAccessor) {
454
- rb_grn_object = ALLOC(RbGrnNamedObject);
455
- rb_grn_object_bind_common(klass, self, rb_context, rb_grn_object,
456
- context, object);
457
- rb_grn_named_object_bind(RB_GRN_NAMED_OBJECT(rb_grn_object),
458
- context, object);
459
441
  } else if (klass == rb_cGrnExpression) {
460
442
  rb_grn_object = ALLOC(RbGrnExpression);
461
443
  rb_grn_object_bind_common(klass, self, rb_context, rb_grn_object,
@@ -815,8 +797,6 @@ rb_grn_object_inspect_content_flags_with_label (VALUE inspected,
815
797
  rb_ary_push(inspected_flags, rb_str_new2("TABLE_DAT_KEY"));
816
798
  if (flags & GRN_OBJ_TABLE_NO_KEY)
817
799
  rb_ary_push(inspected_flags, rb_str_new2("TABLE_NO_KEY"));
818
- if (flags & GRN_OBJ_TABLE_VIEW)
819
- rb_ary_push(inspected_flags, rb_str_new2("TABLE_VIEW"));
820
800
  }
821
801
 
822
802
  switch (object->header.type) {
@@ -1245,7 +1225,6 @@ rb_grn_object_array_reference (VALUE self, VALUE rb_id)
1245
1225
  break;
1246
1226
  case GRN_TYPE:
1247
1227
  case GRN_ACCESSOR: /* FIXME */
1248
- case GRN_ACCESSOR_VIEW: /* FIXME */
1249
1228
  GRN_OBJ_INIT(&value, GRN_BULK, 0, range_id);
1250
1229
  break;
1251
1230
  case GRN_COLUMN_VAR_SIZE:
@@ -1301,7 +1280,6 @@ rb_uvector_value_p (RbGrnObject *rb_grn_object, VALUE rb_value)
1301
1280
  case GRN_TABLE_PAT_KEY:
1302
1281
  case GRN_TABLE_DAT_KEY:
1303
1282
  case GRN_TABLE_NO_KEY:
1304
- case GRN_TABLE_VIEW:
1305
1283
  first_element = rb_ary_entry(rb_value, 0);
1306
1284
  if (rb_respond_to(first_element, rb_intern("record_raw_id"))) {
1307
1285
  return GRN_TRUE;
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -299,5 +299,4 @@ rb_grn_init_table_cursor (VALUE mGrn)
299
299
  rb_grn_init_hash_cursor(mGrn);
300
300
  rb_grn_init_patricia_trie_cursor(mGrn);
301
301
  rb_grn_init_double_array_trie_cursor(mGrn);
302
- rb_grn_init_view_cursor(mGrn);
303
302
  }
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2012 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -2278,5 +2278,4 @@ rb_grn_init_table (VALUE mGrn)
2278
2278
  rb_grn_init_hash(mGrn);
2279
2279
  rb_grn_init_patricia_trie(mGrn);
2280
2280
  rb_grn_init_double_array_trie(mGrn);
2281
- rb_grn_init_view(mGrn);
2282
2281
  }
@@ -1,7 +1,7 @@
1
1
  /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
2
  /* vim: set sts=4 sw=4 ts=8 noet: */
3
3
  /*
4
- Copyright (C) 2009-2011 Kouhei Sutou <kou@clear-code.com>
4
+ Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
5
5
 
6
6
  This library is free software; you can redistribute it and/or
7
7
  modify it under the terms of the GNU Lesser General Public
@@ -62,8 +62,6 @@ rb_grn_inspect_type (unsigned char type)
62
62
  return "cursor-table-dat-key";
63
63
  case GRN_CURSOR_TABLE_NO_KEY:
64
64
  return "cursor-table-no-key";
65
- case GRN_CURSOR_TABLE_VIEW:
66
- return "cursor-table-view";
67
65
  case GRN_CURSOR_COLUMN_INDEX:
68
66
  return "cursor-column-index";
69
67
  case GRN_TYPE:
@@ -80,8 +78,6 @@ rb_grn_inspect_type (unsigned char type)
80
78
  return "table-dat-key";
81
79
  case GRN_TABLE_NO_KEY:
82
80
  return "table-no-key";
83
- case GRN_TABLE_VIEW:
84
- return "table-view";
85
81
  case GRN_DB:
86
82
  return "db";
87
83
  case GRN_COLUMN_FIX_SIZE:
@@ -428,7 +424,7 @@ rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context,
428
424
 
429
425
  string_p = rb_type(object) == T_STRING;
430
426
  table_type_p = (GRN_TABLE_HASH_KEY <= type->header.type &&
431
- type->header.type <= GRN_TABLE_VIEW);
427
+ type->header.type <= GRN_TABLE_NO_KEY);
432
428
 
433
429
  switch (type_id) {
434
430
  case GRN_DB_INT32:
@@ -834,7 +830,7 @@ rb_grn_value_from_ruby_object (VALUE object, grn_ctx *context,
834
830
 
835
831
  string_p = rb_type(object) == T_STRING;
836
832
  table_type_p = (GRN_TABLE_HASH_KEY <= type->header.type &&
837
- type->header.type <= GRN_TABLE_VIEW);
833
+ type->header.type <= GRN_TABLE_NO_KEY);
838
834
  if (!string_p) {
839
835
  return RVAL2GRNBULK_WITH_TYPE(object, context, value, type_id, type);
840
836
  }
data/ext/groonga/rb-grn.h CHANGED
@@ -1,6 +1,6 @@
1
1
  /* -*- c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2012 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -76,7 +76,7 @@ RB_GRN_BEGIN_DECLS
76
76
 
77
77
  #define RB_GRN_MAJOR_VERSION 2
78
78
  #define RB_GRN_MINOR_VERSION 1
79
- #define RB_GRN_MICRO_VERSION 2
79
+ #define RB_GRN_MICRO_VERSION 3
80
80
 
81
81
  #define RB_GRN_QUERY_DEFAULT_MAX_EXPRESSIONS 32
82
82
 
@@ -90,7 +90,6 @@ RB_GRN_BEGIN_DECLS
90
90
  #define RB_GRN_COLUMN(object) ((RbGrnColumn *)(object))
91
91
  #define RB_GRN_INDEX_COLUMN(object) ((RbGrnIndexColumn *)(object))
92
92
  #define RB_GRN_ACCESSOR(object) ((RbGrnAccessor *)(object))
93
- #define RB_GRN_ACCESSOR_VIEW(object) ((RbGrnAccessor *)(object))
94
93
  #define RB_GRN_EXPRESSION(object) ((RbGrnExpression *)(object))
95
94
  #define RB_GRN_SNIPPET(object) ((RbGrnSnippet *)(object))
96
95
  #define RB_GRN_UNBIND_FUNCTION(function) ((RbGrnUnbindFunction)(function))
@@ -222,13 +221,11 @@ RB_GRN_VAR VALUE rb_cGrnHash;
222
221
  RB_GRN_VAR VALUE rb_cGrnPatriciaTrie;
223
222
  RB_GRN_VAR VALUE rb_cGrnDoubleArrayTrie;
224
223
  RB_GRN_VAR VALUE rb_cGrnArray;
225
- RB_GRN_VAR VALUE rb_cGrnView;
226
224
  RB_GRN_VAR VALUE rb_cGrnTableCursor;
227
225
  RB_GRN_VAR VALUE rb_mGrnTableCursorKeySupport;
228
226
  RB_GRN_VAR VALUE rb_cGrnHashCursor;
229
227
  RB_GRN_VAR VALUE rb_cGrnPatriciaTrieCursor;
230
228
  RB_GRN_VAR VALUE rb_cGrnDoubleArrayTrieCursor;
231
- RB_GRN_VAR VALUE rb_cGrnViewCursor;
232
229
  RB_GRN_VAR VALUE rb_cGrnArrayCursor;
233
230
  RB_GRN_VAR VALUE rb_cGrnType;
234
231
  RB_GRN_VAR VALUE rb_cGrnProcedure;
@@ -238,12 +235,10 @@ RB_GRN_VAR VALUE rb_cGrnVariableSizeColumn;
238
235
  RB_GRN_VAR VALUE rb_cGrnIndexColumn;
239
236
  RB_GRN_VAR VALUE rb_cGrnIndexCursor;
240
237
  RB_GRN_VAR VALUE rb_cGrnAccessor;
241
- RB_GRN_VAR VALUE rb_cGrnViewAccessor;
242
238
  RB_GRN_VAR VALUE rb_cGrnGeoPoint;
243
239
  RB_GRN_VAR VALUE rb_cGrnTokyoGeoPoint;
244
240
  RB_GRN_VAR VALUE rb_cGrnWGS84GeoPoint;
245
241
  RB_GRN_VAR VALUE rb_cGrnRecord;
246
- RB_GRN_VAR VALUE rb_cGrnViewRecord;
247
242
  RB_GRN_VAR VALUE rb_cGrnLogger;
248
243
  RB_GRN_VAR VALUE rb_cGrnSnippet;
249
244
  RB_GRN_VAR VALUE rb_cGrnVariable;
@@ -267,14 +262,12 @@ void rb_grn_init_array (VALUE mGrn);
267
262
  void rb_grn_init_hash (VALUE mGrn);
268
263
  void rb_grn_init_patricia_trie (VALUE mGrn);
269
264
  void rb_grn_init_double_array_trie (VALUE mGrn);
270
- void rb_grn_init_view (VALUE mGrn);
271
265
  void rb_grn_init_table_cursor (VALUE mGrn);
272
266
  void rb_grn_init_table_cursor_key_support (VALUE mGrn);
273
267
  void rb_grn_init_array_cursor (VALUE mGrn);
274
268
  void rb_grn_init_hash_cursor (VALUE mGrn);
275
269
  void rb_grn_init_patricia_trie_cursor (VALUE mGrn);
276
270
  void rb_grn_init_double_array_trie_cursor (VALUE mGrn);
277
- void rb_grn_init_view_cursor (VALUE mGrn);
278
271
  void rb_grn_init_type (VALUE mGrn);
279
272
  void rb_grn_init_procedure (VALUE mGrn);
280
273
  void rb_grn_init_column (VALUE mGrn);
@@ -284,10 +277,8 @@ void rb_grn_init_index_column (VALUE mGrn);
284
277
  void rb_grn_init_index_cursor (VALUE mGrn);
285
278
  void rb_grn_init_posting (VALUE mGrn);
286
279
  void rb_grn_init_accessor (VALUE mGrn);
287
- void rb_grn_init_view_accessor (VALUE mGrn);
288
280
  void rb_grn_init_geo_point (VALUE mGrn);
289
281
  void rb_grn_init_record (VALUE mGrn);
290
- void rb_grn_init_view_record (VALUE mGrn);
291
282
  void rb_grn_init_variable (VALUE mGrn);
292
283
  void rb_grn_init_operator (VALUE mGrn);
293
284
  void rb_grn_init_expression (VALUE mGrn);
@@ -538,11 +529,6 @@ VALUE rb_grn_record_new_raw (VALUE table,
538
529
  VALUE id,
539
530
  VALUE values);
540
531
 
541
- VALUE rb_grn_view_record_new (VALUE view,
542
- grn_obj *id);
543
- VALUE rb_grn_view_record_new_raw (VALUE view,
544
- VALUE id);
545
-
546
532
  VALUE rb_grn_record_expression_builder_new (VALUE table,
547
533
  VALUE name);
548
534
  VALUE rb_grn_record_expression_builder_build
@@ -1,6 +1,6 @@
1
1
  /* -*- coding: utf-8; c-file-style: "ruby" -*- */
2
2
  /*
3
- Copyright (C) 2009-2012 Kouhei Sutou <kou@clear-code.com>
3
+ Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
4
4
 
5
5
  This library is free software; you can redistribute it and/or
6
6
  modify it under the terms of the GNU Lesser General Public
@@ -135,10 +135,8 @@ Init_groonga (void)
135
135
  rb_grn_init_procedure(mGrn);
136
136
  rb_grn_init_column(mGrn);
137
137
  rb_grn_init_accessor(mGrn);
138
- rb_grn_init_view_accessor(mGrn);
139
138
  rb_grn_init_geo_point(mGrn);
140
139
  rb_grn_init_record(mGrn);
141
- rb_grn_init_view_record(mGrn);
142
140
  rb_grn_init_variable(mGrn);
143
141
  rb_grn_init_operator(mGrn);
144
142
  rb_grn_init_expression(mGrn);
data/lib/groonga.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  #
3
- # Copyright (C) 2009-2012 Kouhei Sutou <kou@clear-code.com>
3
+ # Copyright (C) 2009-2013 Kouhei Sutou <kou@clear-code.com>
4
4
  #
5
5
  # This library is free software; you can redistribute it and/or
6
6
  # modify it under the terms of the GNU Lesser General Public
@@ -98,4 +98,5 @@ require 'groonga/dumper'
98
98
  require 'groonga/schema'
99
99
  require 'groonga/pagination'
100
100
  require 'groonga/grntest-log'
101
+ require 'groonga/logger'
101
102
  require 'groonga/query-logger'
@@ -75,5 +75,32 @@ module Groonga
75
75
  select = Command::Select.new(self, table, options)
76
76
  select.exec
77
77
  end
78
+
79
+ # Restore commands dumped by "grndump" command.
80
+ #
81
+ # @example
82
+ # dumped_commands = File.read("dump.grn")
83
+ # context.restore(dumped_commands)
84
+ #
85
+ # @param [String] dumped_commands commands dumped by grndump.
86
+ def restore(dumped_commands)
87
+ buffer = ""
88
+ dumped_commands.each_line do |line|
89
+ line = line.chomp
90
+ case line
91
+ when /\\\z/
92
+ buffer << $PREMATCH
93
+ else
94
+ buffer << line
95
+ send(buffer)
96
+ receive
97
+ buffer.clear
98
+ end
99
+ end
100
+ unless buffer.empty?
101
+ send(buffer)
102
+ receive
103
+ end
104
+ end
78
105
  end
79
106
  end
@@ -31,6 +31,16 @@ module Groonga
31
31
 
32
32
  # データベースの内容をgrn式形式の文字列として出力するクラス。
33
33
  class DatabaseDumper
34
+ class << self
35
+ # Dump database
36
+ #
37
+ # TODO: document options paramter
38
+ def dump(options={})
39
+ dumper = new(options)
40
+ dumper.dump
41
+ end
42
+ end
43
+
34
44
  def initialize(options={})
35
45
  @options = options
36
46
  end
@@ -54,11 +64,13 @@ module Groonga
54
64
  dump_plugins(options) if options[:dump_plugins]
55
65
  if options[:dump_schema]
56
66
  schema_dumper.dump_tables
57
- options[:output].write("\n")
58
- schema_dumper.dump_reference_columns
67
+ if schema_dumper.have_reference_columns?
68
+ options[:output].write("\n")
69
+ schema_dumper.dump_reference_columns
70
+ end
59
71
  end
60
72
  dump_tables(options) if options[:dump_tables]
61
- if options[:dump_schema]
73
+ if options[:dump_schema] and schema_dumper.have_index_columns?
62
74
  options[:output].write("\n")
63
75
  schema_dumper.dump_index_columns
64
76
  end
@@ -143,12 +155,24 @@ module Groonga
143
155
  end
144
156
  end
145
157
 
158
+ def have_reference_columns?
159
+ run do |syntax|
160
+ syntax.have_reference_columns?
161
+ end
162
+ end
163
+
146
164
  def dump_reference_columns
147
165
  run do |syntax|
148
166
  syntax.dump_reference_columns
149
167
  end
150
168
  end
151
169
 
170
+ def have_index_columns?
171
+ run do |syntax|
172
+ syntax.have_index_columns?
173
+ end
174
+ end
175
+
152
176
  def dump_index_columns
153
177
  run do |syntax|
154
178
  syntax.dump_index_columns
@@ -210,6 +234,10 @@ module Groonga
210
234
  end
211
235
  end
212
236
 
237
+ def have_reference_columns?
238
+ not reference_columns.empty?
239
+ end
240
+
213
241
  def dump_reference_columns
214
242
  group_columns(reference_columns).each do |table, columns|
215
243
  change_table(table) do
@@ -220,6 +248,10 @@ module Groonga
220
248
  end
221
249
  end
222
250
 
251
+ def have_index_columns?
252
+ not index_columns.empty?
253
+ end
254
+
223
255
  def dump_index_columns
224
256
  group_columns(index_columns).each do |table, columns|
225
257
  change_table(table) do
@@ -0,0 +1,142 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2013 Kouhei Sutou <kou@clear-code.com>
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License version 2.1 as published by the Free Software Foundation.
8
+ #
9
+ # This library is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ # Lesser General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Lesser General Public
15
+ # License along with this library; if not, write to the Free Software
16
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+
18
+ module Groonga
19
+ class Logger
20
+ module Flags
21
+ LABELS = {
22
+ TIME => "time",
23
+ TITLE => "title",
24
+ MESSAGE => "message",
25
+ LOCATION => "location",
26
+ }
27
+
28
+ class << self
29
+ def parse(input, base_flags)
30
+ # TODO
31
+ base_flags
32
+ end
33
+
34
+ def label(flags)
35
+ labels = []
36
+ LABELS.each do |flag, label|
37
+ flags << label if (flags & flag) == flag
38
+ end
39
+ labels << "none" if labels.empty?
40
+ labels.join("|")
41
+ end
42
+ end
43
+ end
44
+
45
+ def log(level, timestamp, title, message, location)
46
+ guard do
47
+ puts("#{timestamp}|#{mark(level)}|#{title} #{message} #{location}")
48
+ end
49
+ end
50
+
51
+ def reopen
52
+ end
53
+
54
+ def fin
55
+ end
56
+
57
+ private
58
+ def guard
59
+ begin
60
+ yield
61
+ rescue Exception
62
+ $stderr.puts("#{$!.class}: #{$!.message}")
63
+ $stderr.puts($@)
64
+ end
65
+ end
66
+
67
+ LEVEL_TO_MARK = {
68
+ :none => " ",
69
+ :emergency => "E",
70
+ :alert => "A",
71
+ :critical => "C",
72
+ :error => "e",
73
+ :warning => "w",
74
+ :notice => "n",
75
+ :debug => "d",
76
+ :dump => "d",
77
+ }
78
+ def mark(level)
79
+ LEVEL_TO_MARK[level] || "-"
80
+ end
81
+ end
82
+
83
+ class FileLogger < Logger
84
+ def initialize(file_name)
85
+ super()
86
+ @file = nil
87
+ @file_name = file_name
88
+ end
89
+
90
+ def reopen
91
+ guard do
92
+ return unless @file
93
+ @file.close
94
+ @file = nil
95
+ end
96
+ end
97
+
98
+ def fin
99
+ guard do
100
+ return unless @file
101
+ @file.close
102
+ end
103
+ end
104
+
105
+ private
106
+ def ensure_open
107
+ return if @file
108
+ @file = File.open(@file_name, "ab")
109
+ end
110
+
111
+ def puts(*arguments)
112
+ ensure_open
113
+ @file.puts(*arguments)
114
+ @file.flush
115
+ end
116
+ end
117
+
118
+ class CallbackLogger < Logger
119
+ def initialize(callback)
120
+ super()
121
+ @callback = callback
122
+ end
123
+
124
+ def log(level, timestamp, title, message, location)
125
+ guard do
126
+ @callback.call(:log, level, timestamp, title, message, location)
127
+ end
128
+ end
129
+
130
+ def reopen
131
+ guard do
132
+ @callback.call(:reopen)
133
+ end
134
+ end
135
+
136
+ def fin
137
+ guard do
138
+ @callback.call(:fin)
139
+ end
140
+ end
141
+ end
142
+ end