Class: AlPersistFile

Inherits:
AlPersist show all
Defined in:
lib/al_persist_file.rb

Overview

Note:

データ本体は、Marshalによるエンコードを行っている。 識別のため、プライマリキーとして:idが自動的に付与される。 検索は使えない。並べ替えは使えない。

データ永続化 単純ファイル版

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods inherited from AlPersist

#[], #[]=, #get_next_offset, #get_previous_offset, #pkey

Constructor Details

- (AlPersistFile) initialize(fname)

constructor

Parameters:

  • (String) fname

    ファイルネーム



43
44
45
46
# File 'lib/al_persist_file.rb', line 43

def initialize( fname )
  super( nil, :id )
  @filename = fname
end

Instance Attribute Details

- (String) filename (readonly)

保存ファイル名

Returns:

  • (String)

    保存ファイル名



36
37
38
# File 'lib/al_persist_file.rb', line 36

def filename
  @filename
end

Class Method Details

+ (AlPersistFile) connect(conn_str = nil)

ファクトリ

Parameters:

  • (String) conn_str (defaults to: nil)

    ファイル名

Returns:



30
31
32
# File 'lib/al_persist_file.rb', line 30

def self.connect( conn_str = nil )
  return self.new( conn_str )
end

Instance Method Details

- (Array<AlPersist>) all

Note:

データ1件を1つのAlPersistオブジェクトとして配列で返す。 一件もデータがない場合は、空の配列を返す。 read()と違って自分は何も変わらず、自分の複製を生産する。

登録データをすべて読み込む。

Returns:

  • (Array<AlPersist>)

    AlPersistオブジェクトの配列



240
241
242
# File 'lib/al_persist_file.rb', line 240

def all()
  search( :limit=>nil, :offset=>nil )
end

- (Boolean) create(values = nil)

Note:

引数の指定があれば、その値を一旦内部値(@values)にしたうえで、 内部値を新規保存する。

データをファイルへ、新規保存する。

Parameters:

  • (Hash) values (defaults to: nil)

    プライマリキーを含む保存する値のHash

Returns:

  • (Boolean)

    成功/失敗



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/al_persist_file.rb', line 94

def create( values = nil )
  @values = values  if values

  file = open( @filename, File::RDWR|File::CREAT )
  file.flock( File::LOCK_EX )

  id = ""
  while (keys = file.gets) && (datas = file.gets)
    id = keys
  end
  id = (id.chomp.to_i + 1).to_s
  @values[:id] = id
  file.puts( id )
  file.puts( Alone::encode_uri_component( Marshal.dump( @values ) ) )
  file.close()

  return true
end

- (Boolean) delete(values = nil)

Note:

valuesには、プライマリキー以外の値が含まれていてもよく、単に無視される。 引数の指定があれば、その値を一旦内部値(@values)にしたうえで削除する。

キーの合致するファイル内のデータを、削除する。

Parameters:

  • (Hash) values (defaults to: nil)

    プライマリキーを含むHash

Returns:

  • (Boolean)

    成功/失敗



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/al_persist_file.rb', line 158

def delete( values = nil )
  @values = values  if values
  return false  if ! @values[:id]
  id = "#{@values[:id]}\n"

  ret = false
  file = open( @filename, 'r' )
  file.flock( File::LOCK_SH )
  fout = Tempfile.new( "al-temp", File.dirname(@filename) )
  while (keys = file.gets) && (datas = file.gets)
    if keys == id
      ret = true
    else
      fout.write( keys )
      fout.write( datas )
    end
  end
  file.close()
  File.rename( fout.path, @filename )
  fout.close()

  return ret
end

- (Boolean) entry(values = nil)

Note:

引数の指定があれば、その値を一旦内部値(@values)にしたうえで登録する。

キーの合致するデータがあれば更新し、なければ新規登録する。

Parameters:

  • (Hash) values (defaults to: nil)

    プライマリキーを含む保存する値のHash

Returns:

  • (Boolean)

    成功/失敗



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/al_persist_file.rb', line 191

def entry( values = nil )
  @values = values  if values
  if @values[:id]
    id = "#{@values[:id]}\n"
  else
    id = nil
  end

  ret = false
  new_id = ""
  file = open( @filename, 'r' )
  file.flock( File::LOCK_SH )
  fout = Tempfile.new( "al-temp", File.dirname(@filename) )
  while (keys = file.gets) && (datas = file.gets)
    new_id = keys
    fout.write( keys )
    if keys == id
      fout.puts( Alone::encode_uri_component( Marshal.dump( @values ) ) )
      ret = true
    else
      fout.write( datas )
    end
  end

  if ! ret
    id = (new_id.chomp.to_i + 1).to_s
    @values[:id] = id
    fout.puts( id )
    fout.puts( Alone::encode_uri_component( Marshal.dump( @values ) ) )
    ret = true
  end

  file.close()
  File.rename( fout.path, @filename )
  fout.close()

  return ret
end

- (Boolean) read(values = nil)

Note:

valuesには、プライマリキー以外の値が含まれていてもよく、単に無視される。

キーを指定してデータを読み込み、内部(@values) に保持する。

Parameters:

  • (Hash) values (defaults to: nil)

    プライマリキーを含むHash

Returns:

  • (Boolean)

    成功/失敗



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/al_persist_file.rb', line 57

def read( values = nil )
  @values = values  if values
  return false  if ! @values[:id]
  id = "#{@values[:id]}\n"

  file = nil
  ret = false
  begin
    file = open( @filename, 'r' )
    file.flock( File::LOCK_SH )

    while (keys = file.gets) && (datas = file.gets)
      if keys == id
        @values = Marshal.load( Alone::decode_uri_component( datas ) )
        ret = true
        break
      end
    end
    file.close()
    
  rescue
    file.close()  if file
  end

  return ret
end

- (Array<AlPersist>) search(param = {})

Note:

データ1件を1つのAlPersistオブジェクトとして配列で返す。 一件もデータがない場合は、空の配列を返す。 read()と違って自分は何も変わらず、自分の複製を生産する。 RDB等と違って、選択パラメータは、limitとoffsetのみ。

登録データを選択的に読み込む。

Parameters:

  • (Hash) param (defaults to: {})

    検索パラメータ

Options Hash (param):

  • (Integer) :limit N/A

    最大取得数

  • (Integer) :offset N/A

    オフセット

Returns:

  • (Array<AlPersist>)

    Persistオブジェクトの配列



258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/al_persist_file.rb', line 258

def search( param = {} )
  #
  # limitとoffsetの調整
  #
  if param[:limit]
    limit = param[:limit].to_i
    limit = 1  if limit < 1
    @search_condition[:limit] = limit
  elsif param.has_key?(:limit)
    @search_condition.delete(:limit)
  end
  if param[:offset]
    offset = param[:offset].to_i
    offset = 0  if offset < 0
    @search_condition[:offset] = offset
  elsif param.has_key?(:offset)
    @search_condition.delete(:offset)
  end

  total_rows = 0
  file = nil
  ret = []
  begin
    file = open( @filename, 'r' )
    file.flock( File::LOCK_SH )
    while (keys = file.gets) && (datas = file.gets)
      total_rows += 1

      if @search_condition[:limit]
        next  if ret.count >= @search_condition[:limit]
        if @search_condition[:offset]
          next  if total_rows <= @search_condition[:offset]
        end
      end

      t = self.dup
      t.values = Marshal.load( Alone::decode_uri_component( datas ) )
      ret << t
    end
    file.close()

  rescue
    file.close()  if file
  end

  @search_condition[:total_rows] = total_rows
  @search_condition[:num_rows] = ret.size
  return ret
end

- (Boolean) update(values = nil)

Note:

引数の指定があれば、その値を一旦内部値(@values)にしたうえで更新する。

キーの合致するファイル内のデータを、更新する。

Parameters:

  • (Hash) values (defaults to: nil)

    プライマリキーを含む更新する値のHash

Returns:

  • (Boolean)

    成功/失敗



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/al_persist_file.rb', line 122

def update( values = nil )
  @values = values  if values
  return false  if ! @values[:id]
  id = "#{@values[:id]}\n"

  ret = false
  file = open( @filename, 'r' )
  file.flock( File::LOCK_SH )
  fout = Tempfile.new( "al-temp", File.dirname(@filename) )
  while (keys = file.gets) && (datas = file.gets)
    if keys == id
      fout.puts( id )
      fout.puts( Alone::encode_uri_component( Marshal.dump( @values ) ) )
      ret = true
    else
      fout.write( keys )
      fout.write( datas )
    end
  end
  file.close()
  File.rename( fout.path, @filename )
  fout.close()

  return ret
end