Dies Aliquanti

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

データベース RubyでPVRを作ろう!その11

iEPGD関連が終わったところまでで、意外に行数を喰ってしまいました。全体で500行以下はさすがにむりかな…

次は予約用のデータベースです。rubyにはdbmとかもあるのですが、ディレ クトリにiEPGDのファイルを保存するだけにします。いまの所、iEPGD情報はせいぜい一週間分ぐらいしか提供されないみたいなので、予約録画件数も 多くても200件ぐらいでしょうから、これでいいことにします。デバッグも楽そうですし… 録画データベースは結局のところ、時間軸で一番直近のものしか興味はないので、Arrayににたインターフェース(メソッド)を用意することにします。
 (Rubyの言語レベルの)マルチスレッドに対応するために、排他制御も含めましたが、どうもmutexではしっくりいかないので、monitorクラスをmixinして、排他制御は片っ端から、synchronize()を使うという、力技というか、エレファントな感じになってしまいました。(ま、動けばいい、ということで・・・)

 

#
# Class ReserveDB (C)2009 B.O.
#  refer below for MonitorMixin
#    http://www.ruby-lang.org/ja/man/html/MonitorMixin.html
require( "monitor")
require( "IEPGD")

class ReserveDB
  @@EXT = "tvpid"
  def initialize( workFolder )
    @workFolder = File::expand_path( workFolder)
    self.extend(MonitorMixin)
    if ! FileTest::directory?( @workFolder)
      Dir::mkdir( @workFolder )
    end
  end #def initialize

  def to_s
    "ReserveDB[#{@workFolder}]"
  end #def to_s
 
  def clear
    synchronize {
      Dir::glob( "#{@workFolder}/*.#{@@EXT}").each {|f|
        File.delete( f )
      }
    }
  end #def clear
 
  def length
    synchronize {
      i = 0
      Dir::glob( "#{@workFolder}/*.#{@@EXT}").each {|f|
        i+= 1
      }
      return i
    }
  end # def length

  def empty?
    length() == 0
  end #def empty?
 
  # adding an iEPGD data
  # needs to check if the same program has existed already
  def push( iEPGo )
    synchronize {
      hash = Hash.new
      del( iEPGo)
      fname = iEPGo.to_s("%D__%T_%eT_%program-title:_%station-name:_%station:.#{@@EXT}" )
      fh = File.open("#{@workFolder}/#{fname}",'w')
      fh.puts( iEPGo.to_s )
      fh.close
    }
  end # def push( iEPG )

  # delete
  # if successful, returns true
  # if not returns nil
  def del( iEPGo )
    hash = Hash.new
    ret = false
    # gather all data in the DB
    synchronize {
      Dir::glob( "#{@workFolder}/*.#{@@EXT}").each {|f|
        if (arrayiEPG= IEPG.File2Array( f)) != nil # in this case, if not nil, length must be 1
          if arrayiEPG[0].sameProgram?( iEPGo )
            File.delete( f )
            ret = true
          end
        end
      }
    }
    return ret
  end # def _del( oiEPG )

  def top
    if empty?
      retrun nil
    end
    hash = Hash.new
    ar = Array.new
    synchronize {
      # gather all data in the DB
      Dir::glob( "#{@workFolder}/*.#{@@EXT}").each {|f|
        if (arrayiEPG= IEPG.File2Array( f)) != nil
            ar += arrayiEPG
        end
      }
    }
    ar.sort!
    return ar[0]
  end # def top
 
  def pop
    synchronize {
      if (tmp = top()) == nil
        return nil
      else
        del( tmp )
        return tmp
      end
    }
  end #def pop
   
end # class ReserveDB < Array



コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://diesaliquanti.blog.fc2.com/tb.php/646-c22511fc
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

まとめ

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。