Class: Milkode::Database

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/milkode/cdweb/lib/database.rb

Defined Under Namespace

Classes: NotFoundPackage

Constant Summary collapse

@@db_dir =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDatabase

Returns a new instance of Database.



32
33
34
# File 'lib/milkode/cdweb/lib/database.rb', line 32

def initialize
  open(Database.dbdir)
end

Instance Attribute Details

#yamlObject (readonly)

Returns the value of attribute yaml.



30
31
32
# File 'lib/milkode/cdweb/lib/database.rb', line 30

def yaml
  @yaml
end

Class Method Details

.dbdirObject



26
27
28
# File 'lib/milkode/cdweb/lib/database.rb', line 26

def self.dbdir
  @@db_dir || Dbdir.default_dir
end

.setup(db_dir) ⇒ Object



22
23
24
# File 'lib/milkode/cdweb/lib/database.rb', line 22

def self.setup(db_dir)
  @@db_dir = db_dir
end

Instance Method Details

#cleanupObject

実体の存在しないデータを削除



173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/milkode/cdweb/lib/database.rb', line 173

def cleanup
  # データベースを開き直す
  reopen_patch

  # クリーンアップ
  records = selectAll2

  records.each do |r|
    unless File.exist? r.path
      yield r if block_given?
      r.record_id.delete
    end
  end
end

#fileList(base) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/milkode/cdweb/lib/database.rb', line 123

def fileList(base)
  base_parts = base.split("/")
  base_depth = base_parts.length

  # 'depth==0'の時はMilkodeYaml#contentsからファイルリストを生成して高速化
  if (base_depth == 0)
    return yaml_load.contents.sort_by{|v| v.name}.map{|v| [v.name, false] }
  end
  
  # shortpathにマッチするものだけに絞り込む
  if (base == "")
    records = @documents.select.records
  else
    records = @documents.select {|record| record.shortpath =~ base }.to_a
  end

  # ファイルリストの生成
  paths = records.map {|record|
    record.shortpath.split("/")
  }.find_all {|parts|
    parts.length > base_depth and parts[0, base_depth] == base_parts
  }.map {|parts|
    is_file = parts.length == base_depth + 1
    path = parts[0, base_depth + 1].join("/")
    [path, is_file]
  }.sort_by {|parts|
    [if parts[1] then 1 else 0 end, parts[0].downcase]
  }.uniq
  
  paths
end

#open(db_dir) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/milkode/cdweb/lib/database.rb', line 40

def open(db_dir)
  dbfile = Dbdir.expand_groonga_path(db_dir)
  
  if File.exist? dbfile
    Groonga::Database.open(dbfile)
  else
    raise "error    : #{dbfile} not found!!"
  end
  
  @documents = Groonga::Context.default["documents"]
end

#path2fpath(path) ⇒ Object



76
77
78
79
# File 'lib/milkode/cdweb/lib/database.rb', line 76

def path2fpath(path)
  pa = path.split("/")
  File.join(convert_packages([pa[0]])[0], pa[1..-1].join('/'))
end

#record(shortpath) ⇒ Object



52
53
54
55
56
# File 'lib/milkode/cdweb/lib/database.rb', line 52

def record(shortpath)
  reopen_patch
  table = @documents.select { |record| record.shortpath == shortpath }
  return table.records[0]
end

#remove_fpath(fpath) ⇒ Object

指定したfpathにマッチするレコードを削除する



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/milkode/cdweb/lib/database.rb', line 156

def remove_fpath(fpath)
  # データベースを開き直す
  reopen_patch
  
  # 削除したいコンテンツを検索
  records, total_records = searchMain([], [], [fpath], [], 0, -1)

  # 検索結果はHashのレコードなので、これを直接deleteしても駄目
  # 1. Record#record_idを使って主キー(Groonga#Arrayのレコード)を取り出し
  # 2. Record#delete で削除
  records.each do |r|
    yield r if block_given?
    r.record_id.delete
  end
end

#search(patterns, packages, current_path, fpaths, suffixs, offset = 0, limit = -1)) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/milkode/cdweb/lib/database.rb', line 58

def search(patterns, packages, current_path, fpaths, suffixs, offset = 0, limit = -1)
  # パッケージ名から絶対パスに変換
  unless packages.empty?
    packages = convert_packages(packages)

    # キーワードがパッケージ名にマッチしなければ検索しない
    return [], 0 if packages.empty?
  else
    # パッケージ名未指定の時は現在位置もfpathsに含める
    if current_path != ""
      fpaths << path2fpath(current_path)
    end
  end
  
  # @todo fpathを厳密に検索するには、検索結果からさらに先頭からのパスではないものを除外する
  records, total_records = searchMain(patterns, packages, fpaths, suffixs, offset, limit)
end

#selectAll(offset = 0, limit = -1)) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/milkode/cdweb/lib/database.rb', line 81

def selectAll(offset = 0, limit = -1)
  table = @documents.select

  # マッチ数
  total_records = table.size
  
  # @todo ここが速度低下の原因?と思ったけど、ここは全て選択の部分だけか・・・

  # 2010/10/29 ongaeshi
  # 本当はこのようにgroongaAPIでソートしたいのだが上手くいかなかった
  #       # ファイル名順にソート
  #       records = table.sort([{:key => "shortpath", :order => "descending"}],
  #                            :offset => offset,
  #                            :limit => limit)

  # ソート
  if (limit != -1)
    records = table.records.sort_by{|record| record.shortpath.downcase }[offset, limit]
  else
    records = table.records.sort_by{|record| record.shortpath.downcase }[offset..limit]
  end

  return records, total_records
end

#selectAll2(offset = 0, limit = -1)) ⇒ Object



106
107
108
109
# File 'lib/milkode/cdweb/lib/database.rb', line 106

def selectAll2(offset = 0, limit = -1)
  records, total_records = selectAll(offset, limit)
  records
end

#totalRecordsObject

レコード数を得る



112
113
114
115
# File 'lib/milkode/cdweb/lib/database.rb', line 112

def totalRecords
  reopen_patch
  @documents.select.size      
end

#yaml_package_numObject

yamlからパッケージの総数を得る



118
119
120
# File 'lib/milkode/cdweb/lib/database.rb', line 118

def yaml_package_num
  yaml_load.contents.size
end

#yaml_reloadObject



36
37
38
# File 'lib/milkode/cdweb/lib/database.rb', line 36

def yaml_reload
  # @yaml = YamlFileWrapper.load_if(@@db_dir || Dbdir.default_dir)
end