estraier 1.4.10
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +0 -0
- data/History.txt +0 -0
- data/README.txt +107 -0
- data/Rakefile +100 -0
- data/bin/estcmd +695 -0
- data/examples/Makefile +31 -0
- data/examples/example001.rb +32 -0
- data/examples/example002.rb +42 -0
- data/ext/estraier.c +1258 -0
- data/ext/extconf.rb +16 -0
- data/lib/estraier.rb +1 -0
- data/lib/estraier/estraier-doc.rb +612 -0
- data/lib/estraier/version.rb +9 -0
- data/setup.rb +1585 -0
- data/test/test_estraier.rb +11 -0
- data/test/test_helper.rb +2 -0
- metadata +73 -0
data/CHANGELOG.txt
ADDED
File without changes
|
data/History.txt
ADDED
File without changes
|
data/README.txt
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
= Ruby Binding of Hyper Estraier
|
2
|
+
|
3
|
+
Hyper Estraier is a full-text search system for communities.
|
4
|
+
|
5
|
+
== Introduction
|
6
|
+
|
7
|
+
This is a package implementing the core API of {Hyper Estraier}[http://hyperestraier.sourceforge.net/], including native codes written in C. As it works on Linux, Mac OS X, Windows, and so on, native libraries for each environment are required to run programs. This package requires Ruby 1.8.4 or later versions.
|
8
|
+
|
9
|
+
== Setting
|
10
|
+
|
11
|
+
Install the latest version of Hyper Estraier.
|
12
|
+
|
13
|
+
Using sudo or pfexec:
|
14
|
+
gem install estraier
|
15
|
+
|
16
|
+
The package `estraier' should be required in each source file of application programs and include the module `Estraier' at pleasure.
|
17
|
+
|
18
|
+
== Example of Gatherer
|
19
|
+
|
20
|
+
The following is the simplest implementation of a gatherer.
|
21
|
+
|
22
|
+
require "estraier"
|
23
|
+
include Estraier
|
24
|
+
|
25
|
+
# create the database object
|
26
|
+
db = Database::new
|
27
|
+
|
28
|
+
# open the database
|
29
|
+
unless db.open("casket", Database::DBWRITER | Database::DBCREAT)
|
30
|
+
printf("error: %s\n", db.err_msg(db.error))
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
|
34
|
+
# create a document object
|
35
|
+
doc = Document::new
|
36
|
+
|
37
|
+
# add attributes to the document object
|
38
|
+
doc.add_attr("@uri", "http://estraier.gov/example.txt")
|
39
|
+
doc.add_attr("@title", "Over the Rainbow")
|
40
|
+
|
41
|
+
# add the body text to the document object
|
42
|
+
doc.add_text("Somewhere over the rainbow. Way up high.")
|
43
|
+
doc.add_text("There's a land that I heard of once in a lullaby.")
|
44
|
+
|
45
|
+
# register the document object to the database
|
46
|
+
unless db.put_doc(doc, Database::PDCLEAN)
|
47
|
+
printf("error: %s\n", db.err_msg(db.error))
|
48
|
+
end
|
49
|
+
|
50
|
+
# close the database
|
51
|
+
unless db.close
|
52
|
+
printf("error: %s\n", db.err_msg(db.error))
|
53
|
+
end
|
54
|
+
|
55
|
+
==Example of Searcher
|
56
|
+
|
57
|
+
The following is the simplest implementation of a searcher.
|
58
|
+
|
59
|
+
require "estraier"
|
60
|
+
include Estraier
|
61
|
+
|
62
|
+
# create the database object
|
63
|
+
db = Database::new
|
64
|
+
|
65
|
+
# open the database
|
66
|
+
unless db.open("casket", Database::DBREADER)
|
67
|
+
printf("error: %s\n", db.err_msg(db.error))
|
68
|
+
exit
|
69
|
+
end
|
70
|
+
|
71
|
+
# create a search condition object
|
72
|
+
cond = Condition::new
|
73
|
+
|
74
|
+
# set the search phrase to the search condition object
|
75
|
+
cond.set_phrase("rainbow AND lullaby")
|
76
|
+
|
77
|
+
# get the result of search
|
78
|
+
result = db.search(cond)
|
79
|
+
|
80
|
+
# for each document in the result
|
81
|
+
dnum = result.doc_num
|
82
|
+
for i in 0...dnum
|
83
|
+
# retrieve the document object
|
84
|
+
doc = db.get_doc(result.get_doc_id(i), 0)
|
85
|
+
next unless doc
|
86
|
+
# display attributes
|
87
|
+
uri = doc.attr("@uri")
|
88
|
+
printf("URI: %s\n", uri) if uri
|
89
|
+
title = doc.attr("@title")
|
90
|
+
printf("Title: %s\n", title) if title
|
91
|
+
# display the body text
|
92
|
+
doc.texts.each do |text|
|
93
|
+
printf("%s\n", text)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# close the database
|
98
|
+
unless db.close
|
99
|
+
printf("error: %s\n", db.err_msg(db.error))
|
100
|
+
end
|
101
|
+
|
102
|
+
== License
|
103
|
+
|
104
|
+
Copyright (C) 2004-2006 Mikio Hirabayashi
|
105
|
+
All rights reserved.
|
106
|
+
|
107
|
+
Hyper Estraier is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License or any later version. Hyper Estraier is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Hyper Estraier; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
data/Rakefile
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'hoe'
|
11
|
+
include FileUtils
|
12
|
+
require File.join(File.dirname(__FILE__), 'lib', 'estraier', 'version')
|
13
|
+
|
14
|
+
AUTHOR = 'Mikio Hirabayashi' # can also be an array of Authors
|
15
|
+
EMAIL = "brett@librum.org"
|
16
|
+
DESCRIPTION = "Native Ruby Hyperestraier interface"
|
17
|
+
GEM_NAME = 'estraier'
|
18
|
+
RUBYFORGE_PROJECT = 'estraier'
|
19
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
20
|
+
|
21
|
+
|
22
|
+
NAME = "estraier"
|
23
|
+
REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
24
|
+
VERS = ENV['VERSION'] || (Estraier::VERSION::STRING + (REV ? ".#{REV}" : ""))
|
25
|
+
CLEAN.include %w[
|
26
|
+
**/.*.sw?
|
27
|
+
*.gem
|
28
|
+
.config
|
29
|
+
ext/*.o
|
30
|
+
ext/*.so
|
31
|
+
ext/Makefile
|
32
|
+
ext/mkmf.log
|
33
|
+
ext/*.bundle
|
34
|
+
**/*~
|
35
|
+
email.txt
|
36
|
+
**/.DS_Store
|
37
|
+
]
|
38
|
+
|
39
|
+
RDOC_OPTS = %w[
|
40
|
+
--quiet
|
41
|
+
--title estraier
|
42
|
+
--opname index.html
|
43
|
+
--line-numbers
|
44
|
+
--main README
|
45
|
+
--inline-source
|
46
|
+
--exclude "^ext/.*\.c"
|
47
|
+
]
|
48
|
+
|
49
|
+
desc 'Update Manifest.txt'
|
50
|
+
task :update_manifest => :clean do
|
51
|
+
sh "find . -type f | sed -e 's%./%%' | grep -v \".svn\" | grep -v \".log\" | grep -v \".cache\" | sort > Manifest.txt"
|
52
|
+
end
|
53
|
+
|
54
|
+
class Hoe
|
55
|
+
def extra_deps
|
56
|
+
@extra_deps.reject { |x| Array(x).first == 'hoe' }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Generate all the Rake tasks
|
61
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
62
|
+
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
63
|
+
p.author = AUTHOR
|
64
|
+
p.description = DESCRIPTION
|
65
|
+
p.email = EMAIL
|
66
|
+
p.summary = DESCRIPTION
|
67
|
+
p.url = HOMEPATH
|
68
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
69
|
+
p.test_globs = ["test/**/test_*.rb"]
|
70
|
+
p.clean_globs = CLEAN #An array of file patterns to delete on clean.
|
71
|
+
# == Optional
|
72
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
73
|
+
p.rdoc_pattern = /(^lib\/estraier\/estraier-doc\.rb|README\.txt)/
|
74
|
+
#p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
75
|
+
p.spec_extras = {
|
76
|
+
:extensions => ['ext/extconf.rb'],
|
77
|
+
:rdoc_options => RDOC_OPTS
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
desc 'Generate website files'
|
83
|
+
task :website_generate do
|
84
|
+
Dir['website/**/*.txt'].each do |txt|
|
85
|
+
sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
desc 'Upload website files to rubyforge'
|
90
|
+
task :website_upload do
|
91
|
+
config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
|
92
|
+
host = "#{config["username"]}@rubyforge.org"
|
93
|
+
remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/"
|
94
|
+
# remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
|
95
|
+
local_dir = 'website'
|
96
|
+
sh %{rsync -av #{local_dir}/ #{host}:#{remote_dir}}
|
97
|
+
end
|
98
|
+
|
99
|
+
desc 'Generate and upload website files'
|
100
|
+
task :website => [:website_generate, :website_upload]
|
data/bin/estcmd
ADDED
@@ -0,0 +1,695 @@
|
|
1
|
+
#! /opt/local/bin/ruby -w
|
2
|
+
#--
|
3
|
+
# Ruby binding of Hyper Estraier
|
4
|
+
# Copyright (C) 2004-2007 Mikio Hirabayashi
|
5
|
+
# This file is part of Hyper Estraier.
|
6
|
+
# Hyper Estraier is free software; you can redistribute it and/or modify it under the terms of
|
7
|
+
# the GNU Lesser General Public License as published by the Free Software Foundation; either
|
8
|
+
# version 2.1 of the License or any later version. Hyper Estraier is distributed in the hope
|
9
|
+
# that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
11
|
+
# License for more details.
|
12
|
+
# You should have received a copy of the GNU Lesser General Public License along with Hyper
|
13
|
+
# Estraier; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
14
|
+
# Boston, MA 02111-1307 USA.
|
15
|
+
|
16
|
+
|
17
|
+
$:.unshift("./src")
|
18
|
+
require "estraier"
|
19
|
+
include Estraier
|
20
|
+
|
21
|
+
|
22
|
+
# global constants
|
23
|
+
PROTVER = "1.0"
|
24
|
+
SEARCHMAX = 10
|
25
|
+
SEARCHAUX = 32
|
26
|
+
SNIPWWIDTH = 480
|
27
|
+
SNIPHWIDTH = 96
|
28
|
+
SNIPAWIDTH = 96
|
29
|
+
VM_ID = 0
|
30
|
+
VM_URI = 1
|
31
|
+
VM_ATTR = 2
|
32
|
+
VM_FULL = 3
|
33
|
+
VM_SNIP = 4
|
34
|
+
|
35
|
+
|
36
|
+
# main routine
|
37
|
+
def main(args)
|
38
|
+
usage if args.length < 1
|
39
|
+
rv = 0
|
40
|
+
case args[0]
|
41
|
+
when "put"
|
42
|
+
rv = runput(args)
|
43
|
+
when "out"
|
44
|
+
rv = runout(args)
|
45
|
+
when "edit"
|
46
|
+
rv = runedit(args)
|
47
|
+
when "get"
|
48
|
+
rv = runget(args)
|
49
|
+
when "uriid"
|
50
|
+
rv = runuriid(args)
|
51
|
+
when "inform"
|
52
|
+
rv = runinform(args)
|
53
|
+
when "optimize"
|
54
|
+
rv = runoptimize(args)
|
55
|
+
when "merge"
|
56
|
+
rv = runmerge(args)
|
57
|
+
when "search"
|
58
|
+
rv = runsearch(args)
|
59
|
+
else
|
60
|
+
usage
|
61
|
+
end
|
62
|
+
return rv
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
# print usage and exit
|
67
|
+
def usage()
|
68
|
+
STDERR.printf("%s: command line utility for the core API of Hyper Estraier\n", $0)
|
69
|
+
STDERR.printf("\n")
|
70
|
+
STDERR.printf("usage:\n")
|
71
|
+
STDERR.printf(" %s put [-cl] [-ws] db [file]\n", $0)
|
72
|
+
STDERR.printf(" %s out [-cl] db expr\n", $0)
|
73
|
+
STDERR.printf(" %s edit db expr name [value]\n", $0)
|
74
|
+
STDERR.printf(" %s get db expr [attr]\n", $0)
|
75
|
+
STDERR.printf(" %s uriid db uri\n", $0)
|
76
|
+
STDERR.printf(" %s inform db\n", $0)
|
77
|
+
STDERR.printf(" %s optimize [-onp] [-ond] db\n", $0)
|
78
|
+
STDERR.printf(" %s merge [-cl] db target\n", $0)
|
79
|
+
STDERR.printf(" %s search [-vu|-va|-vf|-vs] [-gs|-gf|-ga] [-cd] [-ni] [-sf|-sfr|-sfu|-sfi]" \
|
80
|
+
" [-attr expr] [-ord expr] [-max num] [-sk num] [-aux num] [-dis name]" \
|
81
|
+
" db [phrase]\n", $0)
|
82
|
+
STDERR.printf("\n")
|
83
|
+
exit(1)
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
# print error string and flush the buffer */
|
88
|
+
def printerror(msg)
|
89
|
+
STDERR.printf("%s: ERROR: %s\n", $0, msg)
|
90
|
+
STDERR.flush
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
# parse arguments of the put command
|
95
|
+
def runput(args)
|
96
|
+
dbname = nil
|
97
|
+
file = nil
|
98
|
+
opts = 0
|
99
|
+
i = 1
|
100
|
+
while i < args.length
|
101
|
+
if !dbname && args[i] =~ /^-/
|
102
|
+
if args[i] == "-cl"
|
103
|
+
opts |= Database::PDCLEAN
|
104
|
+
elsif args[i] == "-ws"
|
105
|
+
opts |= Database::PDWEIGHT
|
106
|
+
else
|
107
|
+
usage
|
108
|
+
end
|
109
|
+
elsif !dbname
|
110
|
+
dbname = args[i]
|
111
|
+
elsif !file
|
112
|
+
file = args[i]
|
113
|
+
else
|
114
|
+
usage
|
115
|
+
end
|
116
|
+
i += 1
|
117
|
+
end
|
118
|
+
usage if !dbname
|
119
|
+
procput(dbname, file, opts)
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
# parse arguments of the out command
|
124
|
+
def runout(args)
|
125
|
+
dbname = nil
|
126
|
+
expr = nil
|
127
|
+
opts = 0
|
128
|
+
i = 1
|
129
|
+
while i < args.length
|
130
|
+
if !dbname && args[i] =~ /^-/
|
131
|
+
if args[i] == "-cl"
|
132
|
+
opts |= Database::ODCLEAN
|
133
|
+
else
|
134
|
+
usage
|
135
|
+
end
|
136
|
+
elsif !dbname
|
137
|
+
dbname = args[i]
|
138
|
+
elsif !expr
|
139
|
+
expr = args[i]
|
140
|
+
else
|
141
|
+
usage
|
142
|
+
end
|
143
|
+
i += 1
|
144
|
+
end
|
145
|
+
usage if !dbname || !expr
|
146
|
+
procout(dbname, expr, opts)
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
# parse arguments of the edit command
|
151
|
+
def runedit(args)
|
152
|
+
dbname = nil
|
153
|
+
expr = nil
|
154
|
+
name = nil
|
155
|
+
value = nil
|
156
|
+
i = 1
|
157
|
+
while i < args.length
|
158
|
+
if !dbname && args[i] =~ /^-/
|
159
|
+
usage
|
160
|
+
elsif !dbname
|
161
|
+
dbname = args[i]
|
162
|
+
elsif !expr
|
163
|
+
expr = args[i]
|
164
|
+
elsif !name
|
165
|
+
name = args[i]
|
166
|
+
elsif !value
|
167
|
+
value = args[i]
|
168
|
+
else
|
169
|
+
usage
|
170
|
+
end
|
171
|
+
i += 1
|
172
|
+
end
|
173
|
+
usage if !dbname || !expr || !name
|
174
|
+
procedit(dbname, expr, name, value)
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
# parse arguments of the get command
|
179
|
+
def runget(args)
|
180
|
+
dbname = nil
|
181
|
+
expr = nil
|
182
|
+
attr = nil
|
183
|
+
i = 1
|
184
|
+
while i < args.length
|
185
|
+
if !dbname && args[i] =~ /^-/
|
186
|
+
usage
|
187
|
+
elsif !dbname
|
188
|
+
dbname = args[i]
|
189
|
+
elsif !expr
|
190
|
+
expr = args[i]
|
191
|
+
elsif !attr
|
192
|
+
attr = args[i]
|
193
|
+
else
|
194
|
+
usage
|
195
|
+
end
|
196
|
+
i += 1
|
197
|
+
end
|
198
|
+
usage if !dbname || !expr
|
199
|
+
procget(dbname, expr, attr)
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
# parse arguments of the uriid command
|
204
|
+
def runuriid(args)
|
205
|
+
dbname = nil
|
206
|
+
uri = nil
|
207
|
+
i = 1
|
208
|
+
while i < args.length
|
209
|
+
if !dbname && args[i] =~ /^-/
|
210
|
+
usage
|
211
|
+
elsif !dbname
|
212
|
+
dbname = args[i]
|
213
|
+
elsif !uri
|
214
|
+
uri = args[i]
|
215
|
+
else
|
216
|
+
usage
|
217
|
+
end
|
218
|
+
i += 1
|
219
|
+
end
|
220
|
+
usage if !dbname || !uri
|
221
|
+
procuriid(dbname, uri)
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
# parse arguments of the inform command
|
226
|
+
def runinform(args)
|
227
|
+
dbname = nil
|
228
|
+
i = 1
|
229
|
+
while i < args.length
|
230
|
+
if !dbname && args[i] =~ /^-/
|
231
|
+
usage
|
232
|
+
elsif !dbname
|
233
|
+
dbname = args[i]
|
234
|
+
else
|
235
|
+
usage
|
236
|
+
end
|
237
|
+
i += 1
|
238
|
+
end
|
239
|
+
usage if !dbname
|
240
|
+
procinform(dbname)
|
241
|
+
end
|
242
|
+
|
243
|
+
|
244
|
+
# parse arguments of the optimize command
|
245
|
+
def runoptimize(args)
|
246
|
+
dbname = nil
|
247
|
+
opts = 0
|
248
|
+
i = 1
|
249
|
+
while i < args.length
|
250
|
+
if !dbname && args[i] =~ /^-/
|
251
|
+
if args[i] == "-onp"
|
252
|
+
opts |= Database::OPTNOPURGE
|
253
|
+
elsif args[i] == "-ond"
|
254
|
+
opts |= Database::OPTNODBOPT
|
255
|
+
else
|
256
|
+
usage
|
257
|
+
end
|
258
|
+
elsif !dbname
|
259
|
+
dbname = args[i]
|
260
|
+
else
|
261
|
+
usage
|
262
|
+
end
|
263
|
+
i += 1
|
264
|
+
end
|
265
|
+
usage if !dbname
|
266
|
+
procoptimize(dbname, opts)
|
267
|
+
end
|
268
|
+
|
269
|
+
|
270
|
+
# parse arguments of the merge command
|
271
|
+
def runmerge(args)
|
272
|
+
dbname = nil
|
273
|
+
tgname = nil
|
274
|
+
opts = 0
|
275
|
+
i = 1
|
276
|
+
while i < args.length
|
277
|
+
if !dbname && args[i] =~ /^-/
|
278
|
+
if args[i] == "-cl"
|
279
|
+
opts |= Database::MGCLEAN
|
280
|
+
else
|
281
|
+
usage
|
282
|
+
end
|
283
|
+
elsif !dbname
|
284
|
+
dbname = args[i]
|
285
|
+
elsif !tgname
|
286
|
+
tgname = args[i]
|
287
|
+
else
|
288
|
+
usage
|
289
|
+
end
|
290
|
+
i += 1
|
291
|
+
end
|
292
|
+
usage if !dbname || !tgname
|
293
|
+
procmerge(dbname, tgname, opts)
|
294
|
+
end
|
295
|
+
|
296
|
+
|
297
|
+
# parse arguments of the search command
|
298
|
+
def runsearch(args)
|
299
|
+
dbname = nil
|
300
|
+
phrase = nil
|
301
|
+
attrs = []
|
302
|
+
ord = nil
|
303
|
+
max = SEARCHMAX
|
304
|
+
skip = 0
|
305
|
+
opts = 0
|
306
|
+
aux = SEARCHAUX
|
307
|
+
dis = nil
|
308
|
+
cd = false
|
309
|
+
view = VM_ID
|
310
|
+
i = 1
|
311
|
+
while i < args.length
|
312
|
+
if !dbname && args[i] =~ /^-/
|
313
|
+
if args[i] == "-vu"
|
314
|
+
view = VM_URI
|
315
|
+
elsif args[i] == "-va"
|
316
|
+
view = VM_ATTR
|
317
|
+
elsif args[i] == "-vf"
|
318
|
+
view = VM_FULL
|
319
|
+
elsif args[i] == "-vs"
|
320
|
+
view = VM_SNIP
|
321
|
+
elsif args[i] == "-gs"
|
322
|
+
opts |= Condition::SURE
|
323
|
+
elsif args[i] == "-gf"
|
324
|
+
opts |= Condition::FAST
|
325
|
+
elsif args[i] == "-ga"
|
326
|
+
opts |= Condition::AGITO
|
327
|
+
elsif args[i] == "-cd"
|
328
|
+
cd = true
|
329
|
+
elsif args[i] == "-ni"
|
330
|
+
opts |= Condition::NOIDF
|
331
|
+
elsif args[i] == "-sf"
|
332
|
+
opts |= Condition::SIMPLE
|
333
|
+
elsif args[i] == "-sfr"
|
334
|
+
opts |= Condition::ROUGH
|
335
|
+
elsif args[i] == "-sfu"
|
336
|
+
opts |= Condition::UNION
|
337
|
+
elsif args[i] == "-sfi"
|
338
|
+
opts |= Condition::ISECT
|
339
|
+
elsif args[i] == "-attr"
|
340
|
+
usage if (i += 1) >= args.length
|
341
|
+
attrs.push(args[i])
|
342
|
+
elsif args[i] == "-ord"
|
343
|
+
usage if (i += 1) >= args.length
|
344
|
+
ord = args[i]
|
345
|
+
elsif args[i] == "-max"
|
346
|
+
usage if (i += 1) >= args.length
|
347
|
+
max = args[i].to_i
|
348
|
+
elsif args[i] == "-sk"
|
349
|
+
usage if (i += 1) >= args.length
|
350
|
+
skip = args[i].to_i
|
351
|
+
elsif args[i] == "-aux"
|
352
|
+
usage if (i += 1) >= args.length
|
353
|
+
aux = args[i].to_i
|
354
|
+
elsif args[i] == "-dis"
|
355
|
+
usage if (i += 1) >= args.length
|
356
|
+
dis = args[i]
|
357
|
+
else
|
358
|
+
usage
|
359
|
+
end
|
360
|
+
elsif !dbname
|
361
|
+
dbname = args[i]
|
362
|
+
elsif !phrase
|
363
|
+
phrase = args[i]
|
364
|
+
else
|
365
|
+
phrase += " " + args[i]
|
366
|
+
end
|
367
|
+
i += 1
|
368
|
+
end
|
369
|
+
usage if !dbname
|
370
|
+
procsearch(dbname, phrase, attrs, ord, max, skip, opts, aux, dis, cd, view)
|
371
|
+
end
|
372
|
+
|
373
|
+
|
374
|
+
# perform the put command
|
375
|
+
def procput(dbname, file, opts)
|
376
|
+
if file
|
377
|
+
begin
|
378
|
+
ifp = open(file, "rb")
|
379
|
+
draft = ifp.read
|
380
|
+
rescue
|
381
|
+
printerror(file + ": could not open")
|
382
|
+
return 1
|
383
|
+
ensure
|
384
|
+
ifp.close if ifp
|
385
|
+
end
|
386
|
+
else
|
387
|
+
STDIN.binmode
|
388
|
+
draft = STDIN.read
|
389
|
+
end
|
390
|
+
doc = Document::new(draft)
|
391
|
+
db = Database::new
|
392
|
+
unless db.open(dbname, Database::DBWRITER | Database::DBCREAT)
|
393
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
394
|
+
return 1
|
395
|
+
end
|
396
|
+
db.set_informer(Informer::new)
|
397
|
+
unless db.put_doc(doc, opts)
|
398
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
399
|
+
db.close
|
400
|
+
return 1
|
401
|
+
end
|
402
|
+
unless db.close
|
403
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
404
|
+
return 1
|
405
|
+
end
|
406
|
+
return 0
|
407
|
+
end
|
408
|
+
|
409
|
+
|
410
|
+
# perform the out command
|
411
|
+
def procout(dbname, expr, opts)
|
412
|
+
db = Database::new
|
413
|
+
unless db.open(dbname, Database::DBWRITER)
|
414
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
415
|
+
return 1
|
416
|
+
end
|
417
|
+
db.set_informer(Informer::new)
|
418
|
+
id = expr.to_i
|
419
|
+
if id < 1 && (id = db.uri_to_id(expr)) < 1
|
420
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
421
|
+
db.close
|
422
|
+
return 1
|
423
|
+
end
|
424
|
+
unless db.out_doc(id, opts)
|
425
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
426
|
+
db.close
|
427
|
+
return 1
|
428
|
+
end
|
429
|
+
unless db.close
|
430
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
431
|
+
return 1
|
432
|
+
end
|
433
|
+
return 0
|
434
|
+
end
|
435
|
+
|
436
|
+
|
437
|
+
# perform the edit command
|
438
|
+
def procedit(dbname, expr, name, value)
|
439
|
+
db = Database::new
|
440
|
+
unless db.open(dbname, Database::DBWRITER)
|
441
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
442
|
+
return 1
|
443
|
+
end
|
444
|
+
db.set_informer(Informer::new)
|
445
|
+
id = expr.to_i
|
446
|
+
if id < 1 && (id = db.uri_to_id(expr)) < 1
|
447
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
448
|
+
db.close
|
449
|
+
return 1
|
450
|
+
end
|
451
|
+
unless doc = db.get_doc(id, Database::GDNOTEXT)
|
452
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
453
|
+
db.close
|
454
|
+
return 1
|
455
|
+
end
|
456
|
+
doc.add_attr(name, value)
|
457
|
+
unless db.edit_doc(doc)
|
458
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
459
|
+
db.close
|
460
|
+
return 1
|
461
|
+
end
|
462
|
+
unless db.close
|
463
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
464
|
+
return 1
|
465
|
+
end
|
466
|
+
return 0
|
467
|
+
end
|
468
|
+
|
469
|
+
|
470
|
+
# perform the get command
|
471
|
+
def procget(dbname, expr, attr)
|
472
|
+
db = Database::new
|
473
|
+
unless db.open(dbname, Database::DBREADER)
|
474
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
475
|
+
return 1
|
476
|
+
end
|
477
|
+
id = expr.to_i
|
478
|
+
if id < 1 && (id = db.uri_to_id(expr)) < 1
|
479
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
480
|
+
db.close
|
481
|
+
return 1
|
482
|
+
end
|
483
|
+
if attr
|
484
|
+
unless value = db.get_doc_attr(id, attr)
|
485
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
486
|
+
db.close
|
487
|
+
return 1
|
488
|
+
end
|
489
|
+
printf("%s\n", value)
|
490
|
+
else
|
491
|
+
unless doc = db.get_doc(id, 0)
|
492
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
493
|
+
db.close
|
494
|
+
return 1
|
495
|
+
end
|
496
|
+
printf("%s", doc.dump_draft)
|
497
|
+
end
|
498
|
+
unless db.close
|
499
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
500
|
+
return 1
|
501
|
+
end
|
502
|
+
return 0
|
503
|
+
end
|
504
|
+
|
505
|
+
|
506
|
+
# perform the uriid command
|
507
|
+
def procuriid(dbname, uri)
|
508
|
+
db = Database::new
|
509
|
+
unless db.open(dbname, Database::DBREADER)
|
510
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
511
|
+
return 1
|
512
|
+
end
|
513
|
+
unless (id = db.uri_to_id(uri)) > 0
|
514
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
515
|
+
db.close
|
516
|
+
return 1
|
517
|
+
end
|
518
|
+
printf("%d\n", id)
|
519
|
+
unless db.close
|
520
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
521
|
+
return 1
|
522
|
+
end
|
523
|
+
return 0
|
524
|
+
end
|
525
|
+
|
526
|
+
|
527
|
+
# perform the inform command
|
528
|
+
def procinform(dbname)
|
529
|
+
db = Database::new
|
530
|
+
unless db.open(dbname, Database::DBREADER)
|
531
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
532
|
+
return 1
|
533
|
+
end
|
534
|
+
printf("number of documents: %d\n", db.doc_num)
|
535
|
+
printf("number of words: %d\n", db.word_num)
|
536
|
+
printf("file size: %d\n", db.size.to_i)
|
537
|
+
unless db.close
|
538
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
539
|
+
return 1
|
540
|
+
end
|
541
|
+
return 0
|
542
|
+
end
|
543
|
+
|
544
|
+
|
545
|
+
# perform the optimize command
|
546
|
+
def procoptimize(dbname, opts)
|
547
|
+
db = Database::new
|
548
|
+
unless db.open(dbname, Database::DBWRITER)
|
549
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
550
|
+
return 1
|
551
|
+
end
|
552
|
+
db.set_informer(Informer::new)
|
553
|
+
unless db.optimize(opts)
|
554
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
555
|
+
db.close
|
556
|
+
return 1
|
557
|
+
end
|
558
|
+
unless db.close
|
559
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
560
|
+
return 1
|
561
|
+
end
|
562
|
+
return 0
|
563
|
+
end
|
564
|
+
|
565
|
+
|
566
|
+
# perform the merge command
|
567
|
+
def procmerge(dbname, tgname, opts)
|
568
|
+
db = Database::new
|
569
|
+
unless db.open(dbname, Database::DBWRITER)
|
570
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
571
|
+
return 1
|
572
|
+
end
|
573
|
+
db.set_informer(Informer::new)
|
574
|
+
unless db.merge(tgname, opts)
|
575
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
576
|
+
db.close
|
577
|
+
return 1
|
578
|
+
end
|
579
|
+
unless db.close
|
580
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
581
|
+
return 1
|
582
|
+
end
|
583
|
+
return 0
|
584
|
+
end
|
585
|
+
|
586
|
+
|
587
|
+
# perform the search command
|
588
|
+
def procsearch(dbname, phrase, attrs, ord, max, skip, opts, aux, dis, cd, view)
|
589
|
+
db = Database::new
|
590
|
+
unless db.open(dbname, Database::DBREADER)
|
591
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
592
|
+
return 1
|
593
|
+
end
|
594
|
+
cond = Condition::new()
|
595
|
+
cond.set_phrase(phrase) if phrase
|
596
|
+
for i in 0...attrs.length
|
597
|
+
cond.add_attr(attrs[i])
|
598
|
+
end
|
599
|
+
cond.set_order(ord) if ord
|
600
|
+
cond.set_max(max) if max >= 0
|
601
|
+
cond.set_skip(skip) if skip >= 0
|
602
|
+
cond.set_options(opts)
|
603
|
+
cond.set_auxiliary(aux)
|
604
|
+
cond.set_distinct(dis) if dis
|
605
|
+
stime = Time::now.to_f
|
606
|
+
res = db.search(cond)
|
607
|
+
etime = Time::now.to_f
|
608
|
+
border = "--------[" + Time::now.to_f.to_s.gsub(/\./, "") + "]--------"
|
609
|
+
printf("%s\n", border)
|
610
|
+
printf("VERSION\t%s\n", PROTVER)
|
611
|
+
printf("NODE\tlocal\n")
|
612
|
+
printf("HIT\t%d\n", res.hint(""))
|
613
|
+
snwords = []
|
614
|
+
words = res.hint_words
|
615
|
+
for i in 0...words.length
|
616
|
+
word = words[i]
|
617
|
+
hits = res.hint(word)
|
618
|
+
snwords.push(word) if hits > 0
|
619
|
+
printf("HINT#%d\t%s\t%d\n", i + 1, word, hits)
|
620
|
+
end
|
621
|
+
printf("TIME\t%0.3f\n", etime - stime)
|
622
|
+
printf("DOCNUM\t%d\n", db.doc_num())
|
623
|
+
printf("WORDNUM\t%d\n", db.word_num())
|
624
|
+
if view == VM_URI
|
625
|
+
printf("VIEW\tURI\n")
|
626
|
+
elsif view == VM_ATTR
|
627
|
+
printf("VIEW\tATTRIBUTE\n")
|
628
|
+
elsif view == VM_FULL
|
629
|
+
printf("VIEW\tFULL\n")
|
630
|
+
elsif view == VM_SNIP
|
631
|
+
printf("VIEW\tSNIPPET\n")
|
632
|
+
else
|
633
|
+
printf("VIEW\tID\n")
|
634
|
+
end
|
635
|
+
printf("\n")
|
636
|
+
printf("%s\n", border) if view != VM_ATTR && view != VM_FULL && view != VM_SNIP
|
637
|
+
dnum = res.doc_num()
|
638
|
+
for i in 0...dnum
|
639
|
+
id = res.get_doc_id(i)
|
640
|
+
if view == VM_URI
|
641
|
+
next unless doc = db.get_doc(id, cd ? 0 : Database::GDNOTEXT)
|
642
|
+
next if cd && !db.scan_doc(doc, cond)
|
643
|
+
printf("%d\t%s\n", id, doc.attr("@uri"))
|
644
|
+
elsif view == VM_ATTR
|
645
|
+
next unless doc = db.get_doc(id, cd ? 0 : Database::GDNOTEXT)
|
646
|
+
next if cd && !db.scan_doc(doc, cond)
|
647
|
+
printf("%s\n", border)
|
648
|
+
names = doc.attr_names()
|
649
|
+
for j in 0...names.length
|
650
|
+
printf("%s=%s\n", names[j], doc.attr(names[j]))
|
651
|
+
end
|
652
|
+
printf("\n")
|
653
|
+
elsif view == VM_FULL
|
654
|
+
next unless doc = db.get_doc(id, 0)
|
655
|
+
next if cd && !db.scan_doc(doc, cond)
|
656
|
+
printf("%s\n", border)
|
657
|
+
printf("%s", doc.dump_draft())
|
658
|
+
elsif view == VM_SNIP
|
659
|
+
next unless doc = db.get_doc(id, 0)
|
660
|
+
next if cd && !db.scan_doc(doc, cond)
|
661
|
+
printf("%s\n", border)
|
662
|
+
names = doc.attr_names()
|
663
|
+
for j in 0...names.length
|
664
|
+
printf("%s=%s\n", names[j], doc.attr(names[j]))
|
665
|
+
end
|
666
|
+
printf("\n")
|
667
|
+
printf("%s", doc.make_snippet(snwords, SNIPWWIDTH, SNIPHWIDTH, SNIPAWIDTH))
|
668
|
+
else
|
669
|
+
printf("%d\n", id)
|
670
|
+
end
|
671
|
+
end
|
672
|
+
printf("%s:END\n", border)
|
673
|
+
unless db.close
|
674
|
+
printerror(dbname + ": " + db.err_msg(db.error))
|
675
|
+
return 1
|
676
|
+
end
|
677
|
+
return 0
|
678
|
+
end
|
679
|
+
|
680
|
+
|
681
|
+
# class for callback function for database events
|
682
|
+
class Informer
|
683
|
+
def inform(message)
|
684
|
+
printf("%s: INFO: %s\n", $0, message)
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
688
|
+
|
689
|
+
# perform the main routine
|
690
|
+
$0.gsub!(/.*\//, "")
|
691
|
+
exit(main(ARGV))
|
692
|
+
|
693
|
+
|
694
|
+
|
695
|
+
# END OF FILE
|