zoom-0.5.0/0000755000004100000410000000000012572455554012546 5ustar www-datawww-datazoom-0.5.0/Rakefile0000644000004100000410000000170412572455554014215 0ustar www-datawww-data require 'rubygems' require 'rake' require 'rake/clean' require 'rake/testtask' require 'rdoc/task' require 'rake/packagetask' require 'rubygems/package_task' require 'rubygems' require 'mkmf' CLEAN.include '**/*.o' CLEAN.include '**/*.so' CLEAN.include '**/Makefile' CLEAN.include '**/*.log' CLEAN.include 'pkg' task :default => [:build, :test, :package] do |t| end task :build => [:clean] do |t| Dir.chdir('ext') do system('ruby', 'extconf.rb') system('make') end end task :package do system('gem build zoom.gemspec') end Rake::TestTask.new('test') do |t| t.test_files = FileList['test/*_test.rb'] t.ruby_opts = ['-r test/unit', '-I ext', '-r zoom'] t.verbose = true end Rake::TestTask.new('live_test') do |t| t.test_files = FileList['test/*_live.rb'] t.ruby_opts = ['-r test/unit', '-I ext', '-r zoom'] t.verbose = true end Rake::RDocTask.new do |rd| rd.main = "README.md" rd.rdoc_files.include("README.md", "ext/*.c") end zoom-0.5.0/metadata.yml0000644000004100000410000000374712572455554015064 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: zoom version: !ruby/object:Gem::Version version: 0.5.0 platform: ruby authors: - Laurent Sansonetti - Ed Summers autorequire: zoom bindir: bin cert_chain: [] date: 2015-08-15 00:00:00.000000000 Z dependencies: [] description: email: executables: [] extensions: - ext/extconf.rb extra_rdoc_files: [] files: - ChangeLog - README.md - Rakefile - ext/extconf.rb - ext/rbzoom.c - ext/rbzoom.h - ext/rbzoomconnection.c - ext/rbzoomoptions.c - ext/rbzoompackage.c - ext/rbzoomquery.c - ext/rbzoomrecord.c - ext/rbzoomresultset.c - sample/hello.rb - sample/needle.rb - test/package_live.rb - test/package_test.rb - test/record-update.xml - test/record.dat - test/record.txt - test/record.xml - test/search_batch_test.rb - test/search_test.rb - test/thread_test.rb - test/zebra/key/empty_file - test/zebra/lock/empty_file - test/zebra/records/programming_ruby.xml - test/zebra/records/programming_ruby_update.xml - test/zebra/register/empty_file - test/zebra/shadow/empty_file - test/zebra/tab/bib1.att - test/zebra/tab/default.idx - test/zebra/tab/numeric.chr - test/zebra/tab/record.abs - test/zebra/tab/string.chr - test/zebra/tab/usmarc.mar - test/zebra/zebra.cfg homepage: http://ruby-zoom.rubyforge.org licenses: [] metadata: {} post_install_message: rdoc_options: [] require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.4.5 signing_key: specification_version: 4 summary: Ruby/ZOOM provides a Ruby binding to the Z39.50 Object-Orientation Model (ZOOM), an abstract object-oriented programming interface to a subset of the services specified by the Z39.50 standard, also known as the international standard ISO 23950. This version introduces ZOOM Extended Services. test_files: [] zoom-0.5.0/test/0000755000004100000410000000000012572455554013525 5ustar www-datawww-datazoom-0.5.0/test/package_live.rb0000644000004100000410000000572612572455554016476 0ustar www-datawww-dataclass PackageLiveTest < Test::Unit::TestCase # test z39.50 instance that supports extended services by connecting to # zebra instance # # important: you won't be able to run these tests if port 99999 isn't # available def test_crud_record #start the zebra server if it's not already started Dir.chdir("test/zebra") do @pid = fork do STDERR.close exec "zebrasrv tcp:@:99999 -l live_test.log" end end #ensure that the server has time to get up sleep 1 @id = '14055446' @record = File.read('test/zebra/records/programming_ruby.xml') @record_update = File.read('test/zebra/records/programming_ruby_update.xml') #make clean before test ZOOM::Connection.open('localhost:99999/test') do |conn| p = conn.package p.wait_action = 'waitIfPossible' p.action = 'recordDelete' p.record = @record_update p.send('update') p.send('commit') end # create ZOOM::Connection.open('localhost:99999/test') do |conn| p = conn.package p.wait_action = 'waitIfPossible' p.action = 'specialUpdate' p.record = @record p.send('update') p.send('commit') end # make sure it's there ZOOM::Connection.open('localhost:99999/test') do |conn| conn.preferred_record_syntax = 'XML' result_set = conn.search("@attr 1=12 \"#{@id}\"") assert_equal 1, result_set.length end #make sure can search by author ZOOM::Connection.open('localhost:99999/test') do |conn| conn.preferred_record_syntax = 'XML' result_set = conn.search("@attr 1=1 David") assert_equal 1, result_set.length end # update ZOOM::Connection.open('localhost:99999/test') do |conn| p = conn.package p.wait_action = 'waitIfPossible' p.action = 'specialUpdate' p.record = @record_update p.send('update') p.send('commit') end # confirm update record is there ZOOM::Connection.open('localhost:99999/test') do |conn| conn.preferred_record_syntax = 'XML' result_set = conn.search("@attr 1=1 Jason") assert_equal 1, result_set.length end # confirm original record has been written over ZOOM::Connection.open('localhost:99999/test') do |conn| conn.preferred_record_syntax = 'XML' result_set = conn.search("@attr 1=1 David") assert_equal 0, result_set.length end # cleanup ZOOM::Connection.open('localhost:99999/test') do |conn| p = conn.package p.wait_action = 'waitIfPossible' p.action = 'recordDelete' p.record = @record_update p.send('update') p.send('commit') end # make sure the file has been destroyed ZOOM::Connection.open('localhost:99999/test') do |conn| conn.preferred_record_syntax = 'XML' result_set = conn.search("@attr 1=12 \"#{@id}\"") assert_equal 0, result_set.length end Process.kill('TERM', @pid) end end zoom-0.5.0/test/record.xml0000644000004100000410000000305512572455554015530 0ustar www-datawww-data 2007-01-14 18:30:51 http://localhost/site/web_links/show/1.xml
oai:casanova.katipo.co.nz:site:WebLink:2 2007-01-14
http://localhost/site/web_links/show/1 Kete.net This is the site that describes the Kete project. http://kete.net.nz/ kete Sun Jan 14 18:29:54 +1300 2007 admin admin InteractiveResource text/html
zoom-0.5.0/test/search_test.rb0000644000004100000410000000140512572455554016356 0ustar www-datawww-dataclass SearchTest < Test::Unit::TestCase # Walter McGinnis, 2007-08-06 # for some reason the result as string has an extra \n at the end # that now needs to be trimmed off the end # by doing this with a gsub for replacing \n\n pattern with a single \n # if this changes back to a single \n in the future # this shouldn't break def test_search_results ZOOM::Connection.open('z3950.loc.gov', 7090) do |conn| conn.database_name = 'Voyager' conn.preferred_record_syntax = 'USMARC' result_set = conn.search('@attr 1=7 0253333490') assert_equal 1, result_set.length assert_equal File.read('test/record.txt'), result_set[0].to_s.gsub("\n\n", "\n") assert_equal File.read('test/record.dat'), result_set[0].raw end end end zoom-0.5.0/test/search_batch_test.rb0000644000004100000410000000067612572455554017530 0ustar www-datawww-datarequire 'test/unit' require 'zoom' class SearchBatchTest < Test::Unit::TestCase # Terry Reese 9-17-07 # Test for batch results def test_search_batch_test ZOOM::Connection.open('z3950.loc.gov', 7090) do |conn| conn.database_name = 'Voyager' conn.preferred_record_syntax = 'USMARC' result_set = conn.search('@attr 1=4 "Oregon"') records = result_set[0..10] assert_equal 10, records.length end end end zoom-0.5.0/test/record-update.xml0000644000004100000410000000306512572455554017011 0ustar www-datawww-data 2007-01-14 18:30:51 http://localhost/site/web_links/show/1.xml
oai:casanova.katipo.co.nz:site:WebLink:2 2007-01-14
http://localhost/site/web_links/show/1 Kete.net This is the site that describes the Kete project, woohoo! http://kete.net.nz/ kete Sun Jan 14 18:29:54 +1300 2007 admin admin InteractiveResource text/html
zoom-0.5.0/test/zebra/0000755000004100000410000000000012572455554014630 5ustar www-datawww-datazoom-0.5.0/test/zebra/tab/0000755000004100000410000000000012572455554015376 5ustar www-datawww-datazoom-0.5.0/test/zebra/tab/default.idx0000644000004100000410000000215012572455554017526 0ustar www-datawww-data# Zebra indexes as referred to from the *.abs-files. # $Id: default.idx,v 1.15 2007/01/22 18:15:04 adam Exp $ # # Traditional word index # Used if completenss is 'incomplete field' (@attr 6=1) and # structure is word/phrase/word-list/free-form-text/document-text index w completeness 0 position 1 alwaysmatches 1 firstinfield 1 charmap string.chr # Phrase index # Used if completeness is 'complete {sub}field' (@attr 6=2, @attr 6=1) # and structure is word/phrase/word-list/free-form-text/document-text index p completeness 1 charmap string.chr # URX (URL) index # Used if structure=urx (@attr 4=104) index u completeness 0 charmap urx.chr # Numeric index # Used if structure=numeric (@attr 4=109) index n completeness 0 charmap numeric.chr # Null map index (no mapping at all) # Used if structure=key (@attr 4=3) index 0 completeness 0 position 1 charmap @ # Year # Used if structure=year (@attr 4=4) index y completeness 0 charmap @ # Date # Used if structure=date (@attr 4=5) index d completeness 0 charmap @ # Sort register sort s completeness 1 charmap string.chr # Staticrank (uncomment to enable) #staticrank r zoom-0.5.0/test/zebra/tab/bib1.att0000644000004100000410000000674412572455554016740 0ustar www-datawww-data# $Id: bib1.att,v 1.2 2006/05/19 23:45:29 adam Exp $ # Bib-1 Attribute Set name bib1 reference Bib-1 att 1 Personal-name att 2 Corporate-name att 3 Conference-name att 4 Title att 5 Title-series att 6 Title-uniform att 7 ISBN att 8 ISSN att 9 LC-card-number att 10 BNB-card-number att 11 BGF-number att 12 Local-number att 13 Dewey-classification att 14 UDC-classification att 15 Bliss-classification att 16 LC-call-number att 17 NLM-call-number att 18 NAL-call-number att 19 MOS-call-number att 20 Local-classification att 21 Subject-heading att 22 Subject-Rameau att 23 BDI-index-subject att 24 INSPEC-subject att 25 MESH-subject att 26 PA-subject att 27 LC-subject-heading att 28 RVM-subject-heading att 29 Local-subject-index att 30 Date att 31 Date-of-publication att 32 Date-of-acquisition att 33 Title-key att 34 Title-collective att 35 Title-parallel att 36 Title-cover att 37 Title-added-title-page att 38 Title-caption att 39 Title-running att 40 Title-spine att 41 Title-other-variant att 42 Title-former att 43 Title-abbreviated att 44 Title-expanded att 45 Subject-precis att 46 Subject-rswk att 47 Subject-subdivision att 48 Number-natl-biblio att 49 Number-legal-deposit att 50 Number-govt-pub att 51 Number-music-publisher att 52 Number-db att 53 Number-local-call att 54 Code-language att 55 Code-geographic att 56 Code-institution att 57 Name-and-title att 58 Name-geographic att 59 Place-publication att 60 CODEN att 61 Microform-generation att 62 Abstract att 63 Note att 1000 Author-title att 1001 Record-type att 1002 Name att 1003 Author att 1004 Author-name-personal att 1005 Author-name-corporate att 1006 Author-name-conference att 1007 Identifier-standard att 1008 Subject-LC-childrens att 1009 Subject-name-personal att 1010 Body-of-text att 1011 Date/time-added-to-db att 1012 Date/time-last-modified att 1013 Authority/format-id att 1014 Concept-text att 1015 Concept-reference att 1016 Any att 1017 Server-choice att 1018 Publisher att 1019 Record-source att 1020 Editor att 1021 Bib-level att 1022 Geographic-class att 1023 Indexed-by att 1024 Map-scale att 1025 Music-key att 1026 Related-periodical att 1027 Report-number att 1028 Stock-number att 1030 Thematic-number att 1031 Material-type att 1032 Doc-id att 1033 Host-item att 1034 Content-type att 1035 Anywhere att 1036 Author-Title-Subject zoom-0.5.0/test/zebra/tab/usmarc.mar0000644000004100000410000000012412572455554017366 0ustar www-datawww-data# $Id: usmarc.mar,v 1.1 2002/10/22 12:51:09 adam Exp $ name usmarc reference USmarc zoom-0.5.0/test/zebra/tab/record.abs0000644000004100000410000000246012572455554017345 0ustar www-datawww-data# record.abs,v 0.0.1 2007/08/22 jaron encoding utf-8 name marcxml attset bib1.att #attset gils.att esetname F @ esetname B @ marc usmarc.mar systag sysno rank xpath disable all any # melm 000 rtype:n:range(data,06,1),Bib-level:w:range(data,07,01) # xelm /record/leader llength:w:range(data,0,5),rtype:w:range(data,6,1),Bib-level:w:range(data,7,1) # example: xelm /record/leader l1:w:range(data,0,5),l2:w:range(data,10,2) melm 001 Local-number melm 020$a ISBN:w,Identifier-standard:w melm 020 ISBN,Identifier-standard melm 022$a ISSN:w,ISBN:w melm 022 ISSN,Identifier-standard melm 023 Identifier-standard melm 024 Identifier-standard melm 025 Identifier-standard #melm 035 Local-number,Identifier-standard melm 037 Identifier-standard,Stock-number melm 050$b LC-call-number:w, LC-call-number:p, LC-call-number:s melm 050 LC-call-number:w, LC-call-number:p, LC-call-number:s melm 082 Dewey-classification:w,Dewey-classification:s melm 100$a Personal-name melm 245$a Title-cover:w,Title-cover:p,Title-cover:s,Title:w,Title:p,Title:s melm 245$c Author melm 245 Title:w,Title:p melm 246 Title,Title:p,Title-abbreviated,Title-expanded,Title-former melm 247 Title,Title:p,Title-former,Title-other-variant,Related-periodical melm 260$b Publisher:w,Publisher:p melm 260$c Date,Date:s,Date:y zoom-0.5.0/test/zebra/tab/numeric.chr0000644000004100000410000000044312572455554017537 0ustar www-datawww-data# Numeric character map # # $Id: numeric.chr,v 1.1 1997/10/27 14:35:04 adam Exp $ # Define the basic value-set. *Beware* of changing this without re-indexing # your databases. lowercase -{0-9}., uppercase -{0-9}., # Breaking characters space {\001-\040}!"#$%&'\()*+/:;<=>?@\[\\]^_`\{|}~ zoom-0.5.0/test/zebra/tab/string.chr0000644000004100000410000000141212572455554017400 0ustar www-datawww-data# Generic character map. # # $Id: string.chr,v 1.4 1999/09/07 07:19:21 adam Exp $ # Define the basic value-set. *Beware* of changing this without re-indexing # your databases. lowercase {0-9}{a-y}üzæäøöå uppercase {0-9}{A-Y}ÜZÆÄØÖÅ # Breaking characters space {\001-\040}!"#$%&'\()*+,-./:;<=>?@\[\\]^_`\{|}~ # Characters to be considered equivalent for searching purposes. # equivalent æä(ae) # equivalent øö(oe) # equivalent å(aa) # equivalent uü # Supplemental mappings #map (ä) ä #map (æ) æ #map (ø) ø #map (å) å #map (ö) ö #map (Ä) Ä #map (&Aelig;) Æ #map (Ø) Ø #map (Å) Å #map (Ö) Ö #map éÉ e #map á a #map ó o #map í i #map (Aa) (AA) #map (aa) a zoom-0.5.0/test/zebra/shadow/0000755000004100000410000000000012572455554016115 5ustar www-datawww-datazoom-0.5.0/test/zebra/shadow/empty_file0000644000004100000410000000000412572455554020167 0ustar www-datawww-data zoom-0.5.0/test/zebra/register/0000755000004100000410000000000012572455554016454 5ustar www-datawww-datazoom-0.5.0/test/zebra/register/empty_file0000644000004100000410000000000612572455554020530 0ustar www-datawww-data zoom-0.5.0/test/zebra/lock/0000755000004100000410000000000012572455554015560 5ustar www-datawww-datazoom-0.5.0/test/zebra/lock/empty_file0000644000004100000410000000000412572455554017632 0ustar www-datawww-data zoom-0.5.0/test/zebra/records/0000755000004100000410000000000012572455554016271 5ustar www-datawww-datazoom-0.5.0/test/zebra/records/programming_ruby_update.xml0000644000004100000410000001007712572455554023745 0ustar www-datawww-data 01309cam a22003377a 4500 14055446 20070508141530.0 050728s2005 ncua b 001 0 eng d 7 cbc copycat 2 ncip 20 y-gencatlg acquire 2 shelf copies policy default ps05 2005-07-28 z-processor to ASCD jx00 2005-08-04 jx03 2005-08-25 jx03 2005-08-25 to BCCD pv01 2005-10-04 copy 2 to BCCD 2005299026 GBA463977 bnb 012981880 Uk 0974514055 (pbk.) (OCoLC)ocm56965958 UKM UKM OCLCQ TXH DLC lccopycat QA76.64 .T494 2005 005.133 22 Thomas, Jason, 1956- Programming Ruby : the pragmatic programmers' guide / Dave Thomas with Chad Fowler and Andy Hunt. 2nd ed. Raleigh, N.C. : Pragmatic Bookshelf, c2005. xxxii, 830 p. : ill. ; 24 cm. Includes bibliographical references and index. Object-oriented programming (Computer science) Ruby (Computer program language) Fowler, Chad. Hunt, Andrew, 1964- Publisher description http://www.loc.gov/catdir/enhancements/fy0715/2005299026-d.html zoom-0.5.0/test/zebra/records/programming_ruby.xml0000644000004100000410000001007712572455554022403 0ustar www-datawww-data 01309cam a22003377a 4500 14055446 20070508141530.0 050728s2005 ncua b 001 0 eng d 7 cbc copycat 2 ncip 20 y-gencatlg acquire 2 shelf copies policy default ps05 2005-07-28 z-processor to ASCD jx00 2005-08-04 jx03 2005-08-25 jx03 2005-08-25 to BCCD pv01 2005-10-04 copy 2 to BCCD 2005299026 GBA463977 bnb 012981880 Uk 0974514055 (pbk.) (OCoLC)ocm56965958 UKM UKM OCLCQ TXH DLC lccopycat QA76.64 .T494 2005 005.133 22 Thomas, David, 1956- Programming Ruby : the pragmatic programmers' guide / Dave Thomas with Chad Fowler and Andy Hunt. 2nd ed. Raleigh, N.C. : Pragmatic Bookshelf, c2005. xxxii, 830 p. : ill. ; 24 cm. Includes bibliographical references and index. Object-oriented programming (Computer science) Ruby (Computer program language) Fowler, Chad. Hunt, Andrew, 1964- Publisher description http://www.loc.gov/catdir/enhancements/fy0715/2005299026-d.html zoom-0.5.0/test/zebra/key/0000755000004100000410000000000012572455554015420 5ustar www-datawww-datazoom-0.5.0/test/zebra/key/empty_file0000644000004100000410000000000412572455554017472 0ustar www-datawww-data zoom-0.5.0/test/zebra/zebra.cfg0000644000004100000410000000144612572455554016421 0ustar www-datawww-data# Simple Zebra configuration file that defines # a database with MARCXML records. # # Where are the config files located? profilePath:tab # modulePath - where to look for loadable zebra modules # modulePath: /usr/lib/idzebra-2.0/modules encoding: UTF-8 # Files that describe the attribute sets supported. attset: bib1.att attset: explain.att attset: gils.att # systag sysno rank # Specify record type #iso2709.recordType:grs.marcxml.record recordType:grs.xml recordId: (bib1,Local-number) #recordId: file storeKeys:1 storeData:1 database: test # Lock File Area lockDir: lock perm.anonymous:rw register: register:1M shadow: shadow:1M # Temp File area for result sets #setTmpDir: /home/ # Temp File area for index program keyTmpDir: key # Approx. Memory usage during indexing memMax: 125M rank:rank-1 zoom-0.5.0/test/package_test.rb0000644000004100000410000000227312572455554016510 0ustar www-datawww-dataclass TestPackage < Test::Unit::TestCase def setup @connection = ZOOM::Connection.new end def test_connection_package assert(@connection.respond_to?('package')) p = @connection.package assert_equal(p.class.to_s, 'ZOOM::Package') end def test_option_returns_same_value p = @connection.package p.action = 'update' assert_equal('update', p.action) end def test_options_containing_hyphen # option contact-name p = @connection.package assert(p.respond_to?('contact_name')) assert(p.respond_to?('contact_name=')) assert(p.respond_to?('set_contact_name')) p.contact_name = 'contact_name value' assert_equal('contact_name value', p.contact_name) end def test_option_containing_fullstop #option correlationInfo.note p = @connection.package assert(p.respond_to?('correlation_info_note')) assert(p.respond_to?('correlation_info_note=')) assert_equal(true, p.respond_to?('set_correlation_info_note')) p.correlation_info_note = 'correlation_info_note value' assert_equal('correlation_info_note value', p.correlation_info_note) end end zoom-0.5.0/test/record.txt0000644000004100000410000000200012572455554015534 0ustar www-datawww-data01109cam 2200277 a 4500 001 708964 005 19980710092633.8 008 970604s1997 inuab b 001 0 eng 035 $9 (DLC) 97023698 906 $a 7 $b cbc $c orignew $d 1 $e ocip $f 19 $g y-gencatlg 955 $a pc16 to ja00 06-04-97; jd25 06-05-97; jd99 06-05-97; jd11 06-06-97;aa05 06-10-97; CIP ver. pv08 11-05-97 010 $a 97023698 020 $a 0253333490 (alk. paper) 040 $a DLC $c DLC $d DLC 050 00 $a QE862.D5 $b C697 1997 082 00 $a 567.9 $2 21 245 04 $a The complete dinosaur / $c edited by James O. Farlow and M.K. Brett-Surman ; art editor, Robert F. Walters. 260 $a Bloomington : $b Indiana University Press, $c c1997. 300 $a xi, 752 p. : $b ill. (some col.), maps ; $c 26 cm. 504 $a Includes bibliographical references and index. 650 0 $a Dinosaurs. 700 1 $a Farlow, James Orville. 700 2 $a Brett-Surman, M. K., $d 1950- 920 $a **LC HAS REQ'D # OF SHELF COPIES** 991 $b c-GenColl $h QE862.D5 $i C697 1997 $t Copy 1 $w BOOKS 991 $b r-SciRR $h QE862.D5 $i C697 1997 $t Copy 1 $w GenBib bi 98-003434 zoom-0.5.0/test/record.dat0000644000004100000410000000212512572455554015475 0ustar www-datawww-data01109cam 2200277 a 450000100070000000500170000700800410002403500210006590600450008695501090013101000170024002000280025704000180028505000240030308200140032724501100034126000530045130000510050450400510055565000150060670000270062170000320064892000390068099100500071999100620076970896419980710092633.8970604s1997 inuab b 001 0 eng  9(DLC) 97023698 a7bcbccorignewd1eocipf19gy-gencatlg apc16 to ja00 06-04-97; jd25 06-05-97; jd99 06-05-97; jd11 06-06-97;aa05 06-10-97; CIP ver. pv08 11-05-97 a 97023698  a0253333490 (alk. paper) aDLCcDLCdDLC00aQE862.D5bC697 199700a567.922104aThe complete dinosaur /cedited by James O. Farlow and M.K. Brett-Surman ; art editor, Robert F. Walters. aBloomington :bIndiana University Press,cc1997. axi, 752 p. :bill. (some col.), maps ;c26 cm. aIncludes bibliographical references and index. 0aDinosaurs.1 aFarlow, James Orville.2 aBrett-Surman, M. K.,d1950- a**LC HAS REQ'D # OF SHELF COPIES** bc-GenCollhQE862.D5iC697 1997tCopy 1wBOOKS br-SciRRhQE862.D5iC697 1997tCopy 1wGenBib bi 98-003434zoom-0.5.0/test/thread_test.rb0000644000004100000410000000120012572455554016351 0ustar www-datawww-dataclass SearchTest < Test::Unit::TestCase # Jason Ronallo, 2007-09-20 # With libyaz3 3.0.12 threading fails for gem at # point of retrieving a record out of a result set. # libyaz3 3.0.10 worked fine. # Update: 3.0.14 fixes the problem. def test_thread thread = Thread.new do ZOOM::Connection.open('z3950.loc.gov', 7090) do |conn| conn.database_name = 'Voyager' conn.preferred_record_syntax = 'USMARC' result_set = conn.search('nature') array = result_set[0, 6] #change the 2nd number assert_equal 6, array.length #change the number end end thread.join end end zoom-0.5.0/sample/0000755000004100000410000000000012572455554014027 5ustar www-datawww-datazoom-0.5.0/sample/hello.rb0000644000004100000410000000032712572455554015461 0ustar www-datawww-datarequire 'zoom' ZOOM::Connection.open('z3950.loc.gov', 7090) do |conn| conn.database_name = 'Voyager' conn.preferred_record_syntax = 'USMARC' rset = conn.search('@attr 1=7 0253333490') p rset[0] end zoom-0.5.0/sample/needle.rb0000755000004100000410000000651212572455554015617 0ustar www-datawww-data#!/usr/bin/ruby -w # # Given a list of ISBNs and Z39.50 servers, try to get a MARC record # for each book. The servers listed here seem to be the best # worldwide. If an ISBN cannot be found then we use the xisbn service # to try different editions. # # TODO: If more then one record is found, pick the longest one. # # By Devin Bayer - Summer 2006 - Public Domain # # require 'rubygems' require 'zoom' require 'net/http' Net::HTTP.version_1_2 require 'rexml/document' servers_source = [ # Server, Username, Password [ 'z3950.loc.gov:7090/Voyager' ], # Library of Congress [ 'amicus.nlc-bnc.ca/ANY', 'akvadrako', 'aw4gliu' ], # Canada [ 'catnyp.nypl.org:210/INNOPAC' ], # New York Public [ 'z3950.copac.ac.uk:2100/COPAC' ], # United Kingdom [ 'z3950.btj.se:210/BURK' ], # Sweden [ '195.249.206.204:210/Default' ], # DenMark [ 'library.ox.ac.uk:210/ADVANCE' ], # Oxford [ '216.16.224.199:210/INNOPAC' ], # Cambridge [ 'prodorbis.library.yale.edu:7090/Voyager' ], # Yale [ 'zsrv.library.northwestern.edu:11090/Voyager' ]] # NorthWestern University ######################################### # Connect to each server ######################################### @servers = Array.new servers_source.each do |array| tries = 0 $stderr.puts 'INFO: connecting to ' + array[0] begin con = ZOOM::Connection.new() con.preferred_record_syntax = 'MARC21' con.element_set_name = 'F' if array[1] then con.user = array[1] con.password = array[2] end con.connect(array[0]) @servers << con rescue RuntimeError $stderr.puts 'ERROR: connecting to ' + array[0] + ': ' + $! tries += 1 retry if tries < 3 $stderr.puts 'WARNING: giving up on ' + array[0] end end ################################# # search for ISBN on each server # return true if found ################################# def search(isbn) @servers.each do |con| begin rset = con.search("@attr 1=7 #{isbn}") if rset.size > 0 and rset[0].to_s.chomp.length > 1 then $stderr.puts con.host + ': ' + isbn + ': ' + rset.size.to_s + ' records' puts rset[0].raw('marc8') return true end rescue RuntimeError $stderr.puts 'WARNING: ' + con.host + ': ' + isbn + ': ' + $! end end return false end ######################################### # Lookup each ISBN ######################################### failed_isbns = Array.new xisbn = Net::HTTP.new('labs.oclc.org') File.open('isbns').each_line do |isbn| isbn = isbn.chomp.upcase next if isbn.length < 1 if not search(isbn) then tries = 0 # Try alternate editions begin xisbn.start if not xisbn.started? xml = xisbn.get("/xisbn/#{isbn}").body rescue SocketError, Errno::ECONNRESET, Errno::EPIPE, EOFError, Timeout::Error xisbn.finish if xisbn.started? if tries < 3 then tries += 1 retry else $stderr.puts "ERROR: xisbn failure: " + $! end end found = false REXML::Document.new(xml).root.each_element do |elem| alt = elem.texts.to_s.chomp.upcase next if alt == isbn if search(alt) then $stderr.puts "INFO: alternate for #{isbn}: #{alt}" found = true break end end if not found then $stderr.puts "INFO: isbn #{isbn} not found" failed_isbns << isbn end end end if failed_isbns.size > 0 then $stderr.puts "ISBN's not found:" failed_isbns.each { |isbn| $stderr.puts isbn } end zoom-0.5.0/ChangeLog0000644000004100000410000000752412572455554014330 0ustar www-datawww-datav0.4.1 Tue Nov 20 08:05:53 EST 2007 - record retrieval has changed with batch_download branch merged into trunk. this allows for records to be downloaded in a batch and tries to fall back to record at a time download if batch download fails. - removed second definition of databaseName from rbzoompackage.c - added RDoc style documentation to C source - added tests for batch retrieval and a connection within a Thread v0.4.0 - checking in support of ZOOM::Connection#package - creating a .4 version of gem - added Walter McGinnis, Nicolai Moles-Benfell To Authors - src/rbzoomoptions.c: Added support for rubyfying option names that contain hyphens or full stops. - src/rbzoomconnection.c: Added ZOOM::Connection#package, a factory method that returns an instance of a ZOOM::Package object. - added src/rbzoompackage.c: v0.3.0 Tue Jul 10 11:57:40 EDT 2007 - new format for this file, all changes are summarized under a version no need to recreate commit messages in a text file when svn can tell us them - added Rakefile - applied patch from Jason Ronallo to enable raw method on records - added test suite - created gem for rubyforge 2007-05-05 Ed Summers - added Ed Summers - src/lib/* removed marc.rb since it isn't used and conflicts with the marc gem # Older format preserved for posterity ... 2006-09-21 Laurent Sansonetti * ChangeLog, README, src/**/*.{c,h,rb}: s/gnome.org/chopine.be/g. 2006-09-21 Devin Bayer * .cvsignore: Ignores zoom.bundle. * sample/needle.rb: Updated the needle demo application. * src/rbzoomconnection.c: Do not fail when reading options. 2006-08-22 Laurent Sansonetti * AUTHORS: - Updated my e-mail address ; - Added Devin. 2006-08-22 Devin Bayer * src/rbzoomrecord.c: Added ZOOM::Record#raw, to grab a marc record in marc format. 2006-08-20 Devin Bayer * sample/needle.rb: Added new sample, contributed by Devin Bayer. === Ruby/ZOOM 0.2.2 === 2005-11-08 Laurent Sansonetti * README: Added a note about YAZ's --enable-shared problem. * AUTHORS: Added Pascal and Matt. 2005-11-08 Matt Vanderpol * src/rbzoomquery.c (.new_prefix, .new_cql): Fixed constructors. === Ruby/ZOOM 0.2.1 === 2005-09-23 Pascal Terjan * src/rbzoomoptions.c: Fixes segfault when rubyfying the option name. === Ruby/ZOOM 0.2.0 === 2005-08-02 Laurent Sansonetti * src/rbzoomresultset.rb (#[]): Retrieves the record one by one using ZOOM_resultset_record instead of getting them all in once with ZOOM_resultset_records (for a strange reason sometimes the resultset was not empty but ZOOM_resultset_records used to return empty records). 2005-07-19 Laurent Sansonetti * src/lib/marc.rb: Added an experimental MARC decoder. === Ruby/ZOOM 0.1.0 === 2005-03-18 Laurent Sansonetti * COPYING.LIB, AUTHORS, README: Added. * src/rbzoomconnection.c, src/rbzoomquery.c: Fixed documentation. * src/rbzoomresultset.c (#[]): - Range objects are supported ; - Do not clone nil objects. 2005-03-17 Laurent Sansonetti * doc/.cvsignore, doc/gendoc.sh: Added. * src/rbzoom.c, src/rbzoom.h, src/rbzoomconnection.c, src/rbzoomoptions.c, src/rbzoomquery.c, src/rbzoomrecord.c, src/rbzoomresultset.c: Added extdoc documentation + LGPL headers. 2005-03-16 Laurent Sansonetti * src/rbzoomrecord.c (#database, #syntax, #render, #xml): Added. * src/rbzoom.c, sample/hello.rb: Renamed the module name as 'ZOOM'. 2005-03-14 Laurent Sansonetti Initial RubyForge revision. zoom-0.5.0/ext/0000755000004100000410000000000012572455554013346 5ustar www-datawww-datazoom-0.5.0/ext/rbzoomresultset.c0000644000004100000410000001640312572455554017001 0ustar www-datawww-data/* * Copyright (C) 2005 Laurent Sansonetti * * This library 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 (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rbzoom.h" #ifdef MAKING_RDOC_HAPPY mZoom = rb_define_module("ZOOM"); #endif /* Class: ZOOM::ResultSet * The result set object is a container for records returned from a target. */ static VALUE cZoomResultSet; VALUE rbz_resultset_make (ZOOM_resultset resultset) { return resultset != NULL ? Data_Wrap_Struct (cZoomResultSet, NULL, ZOOM_resultset_destroy, resultset) : Qnil; } static ZOOM_resultset rbz_resultset_get (VALUE obj) { ZOOM_resultset resultset; Data_Get_Struct (obj, struct ZOOM_resultset_p, resultset); assert (resultset != NULL); return resultset; } /* * call-seq: * set_option(key, value) * * key: the name of the option, as a string. * * value: the value of this option (as a string, integer or boolean). * * Sets an option on the result set. * * Returns: self. */ static VALUE rbz_resultset_set_option (VALUE self, VALUE key, VALUE val) { ZOOM_resultset_option_set (rbz_resultset_get (self), RVAL2CSTR (key), RVAL2CSTR (rb_obj_as_string (val))); return self; } /* * call-seq: * get_option(key) * * key: the name of the option, as a string. * * Gets the value of a result set's option. * * Returns: the value of the given option, as a string, integer or boolean. */ static VALUE rbz_resultset_get_option (VALUE self, VALUE key) { const char *value; value = ZOOM_resultset_option_get (rbz_resultset_get (self), RVAL2CSTR (key)); return zoom_option_value_to_ruby_value (value); } /* * Returns: the number of hits. */ static VALUE rbz_resultset_size (VALUE self) { return INT2NUM (ZOOM_resultset_size (rbz_resultset_get (self))); } /* * call-seq: * [](key) * * key: either an integer, a range or an interval of 2 integers. * * Retrieves one or many records from the result set, according to the given * key. * * # Gets the first record. * rset[0] * # Gets the first, second and third records. * rset[1..3] * # Gets three records starting from the second one. * rset[2, 3] * * Returns: one or many references to ZOOM::Record objects. */ static VALUE rbz_resultset_index (int argc, VALUE *argv, VALUE self) { ZOOM_record *records; ZOOM_record record; VALUE ary; size_t begin; size_t count; size_t i; if (argc == 1) { VALUE arg = argv [0]; if (TYPE (arg) == T_FIXNUM || TYPE (arg) == T_BIGNUM) { record = ZOOM_resultset_record (rbz_resultset_get (self), NUM2LONG (arg)); return record != NULL ? rbz_record_make (ZOOM_record_clone (record)) : Qnil; } if (CLASS_OF (arg) == rb_cRange) { begin = NUM2LONG (rb_funcall (arg, rb_intern ("begin"), 0)); count = NUM2LONG (rb_funcall (arg, rb_intern ("end"), 0)); count -= begin; } else rb_raise (rb_eArgError, "Invalid argument of type %s (not Numeric or Range)", rb_class2name (CLASS_OF (arg))); } else { VALUE rb_begin; VALUE rb_count; rb_scan_args (argc, argv, "2", &rb_begin, &rb_count); begin = NUM2LONG (rb_begin); count = NUM2LONG (rb_count); } ary = rb_ary_new (); if (count == 0) return ary; /* Allocate array */ records = ALLOC_N (ZOOM_record, count); /* Download records in batches */ ZOOM_resultset_records (rbz_resultset_get (self), records, begin, count); /* Test the first record in the set. If null, then fall back. If valid, * generate the ruby array. */ if (records[0]!=NULL) { for (i = 0; i < count; i++) /* We don't want any null records -- if there is on in the resultset, * ignore it. */ if (records[i]!=NULL) rb_ary_push (ary, rbz_record_make (ZOOM_record_clone (records [i]))); } else { /* This is our fallback function * It exists for those anomalies where the server * will not respect the batch request and will return just * a null array (per change request 36 where Laurent Sansonetti notes * Retrieves the record one by one using ZOOM_resultset_record instead * of getting them all in once with ZOOM_resultset_records (for a strange * reason sometimes the resultset was not empty but ZOOM_resultset_records * used to return empty records). */ for (i = 0; i < count; i++) { record = ZOOM_resultset_record (rbz_resultset_get (self), begin + i); /* Ignore null records */ if (record != NULL) rb_ary_push (ary, rbz_record_make (ZOOM_record_clone (record))); } } return ary; } /* * Lists the records inside the result set. * * Returns: an array of ZOOM::Record objects. */ static VALUE rbz_resultset_records (VALUE self) { VALUE argv [2]; argv [0] = INT2FIX (0); argv [1] = rbz_resultset_size (self); return rbz_resultset_index (2, argv, self); } /* * call-seq: * each_record { |record| ... } * * Parses the records inside the result set and call the given block for each * record, passing a reference to a ZOOM::Record object as parameter. * * Returns: self. */ static VALUE rbz_resultset_each_record (VALUE self) { rb_ary_each (rbz_resultset_records (self)); return self; } void Init_zoom_resultset (VALUE mZoom) { VALUE c; c = rb_define_class_under (mZoom, "ResultSet", rb_cObject); rb_undef_method (CLASS_OF (c), "new"); rb_define_method (c, "set_option", rbz_resultset_set_option, 2); rb_define_method (c, "get_option", rbz_resultset_get_option, 1); define_zoom_option (c, "start"); define_zoom_option (c, "count"); define_zoom_option (c, "presentChunk"); define_zoom_option (c, "elementSetName"); define_zoom_option (c, "preferredRecordSyntax"); define_zoom_option (c, "schema"); define_zoom_option (c, "setname"); rb_define_method (c, "size", rbz_resultset_size, 0); rb_define_alias (c, "length", "size"); rb_define_method (c, "records", rbz_resultset_records, 0); rb_define_method (c, "each_record", rbz_resultset_each_record, 0); rb_define_method (c, "[]", rbz_resultset_index, -1); cZoomResultSet = c; } zoom-0.5.0/ext/extconf.rb0000644000004100000410000000046212572455554015343 0ustar www-datawww-datarequire 'mkmf' unless system('yaz-config') $stderr.puts 'yaz does not appear to be installed' exit end unless have_header('yaz/zoom.h') $stderr.puts 'yaz zoom header not available' exit end $CFLAGS << " #{`yaz-config --cflags`} " $LDFLAGS << " #{`yaz-config --libs`} " create_makefile("zoom") zoom-0.5.0/ext/rbzoomquery.c0000644000004100000410000000557512572455554016124 0ustar www-datawww-data/* * Copyright (C) 2005 Laurent Sansonetti * * This library 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 (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rbzoom.h" #ifdef MAKING_RDOC_HAPPY mZoom = rb_define_module("ZOOM"); #endif /* Class: ZOOM::Query * Search queries. */ static VALUE cZoomQuery; static VALUE rbz_query_make (ZOOM_query query) { return query != NULL ? Data_Wrap_Struct (cZoomQuery, NULL, ZOOM_query_destroy, query) : Qnil; } ZOOM_query rbz_query_get (VALUE obj) { ZOOM_query query; Data_Get_Struct (obj, struct ZOOM_query_p, query); assert (query != NULL); return query; } /* * call-seq: new_prefix(prefix) * * prefix: PQF notation. * * Creates a RPN query using the given PQF notation. * * Returns: a newly created ZOOM::Query object. */ static VALUE rbz_query_new_prefix (VALUE self, VALUE prefix) { ZOOM_query query; query = ZOOM_query_create (); ZOOM_query_prefix (query, RVAL2CSTR (prefix)); return rbz_query_make (query); } /* call-seq: * new_cql(prefix) * * prefix: CQL notation. * * Creates a CQL query using the given CQL notation. * * Returns: a newly created ZOOM::Query object. */ static VALUE rbz_query_new_cql (VALUE self, VALUE cql) { ZOOM_query query; query = ZOOM_query_create (); ZOOM_query_cql (query, RVAL2CSTR (cql)); return rbz_query_make (query); } /* * call-seq: new_sort_by(criteria) * * criteria: a sort criteria. * * Creates a sort query from the YAZ sorting notation. * * Returns: a newly created ZOOM::Query object. */ static VALUE rbz_query_new_sort_by (VALUE self, VALUE criteria) { ZOOM_query query; query = ZOOM_query_create (); ZOOM_query_sortby (rbz_query_get (self), RVAL2CSTR (criteria)); return rbz_query_make (query); } void Init_zoom_query (VALUE mZoom) { VALUE c; c = rb_define_class_under (mZoom, "Query", rb_cObject); rb_define_singleton_method (c, "new_prefix", rbz_query_new_prefix, 1); rb_define_singleton_method (c, "new_cql", rbz_query_new_cql, 1); rb_define_singleton_method (c, "new_sort_by", rbz_query_new_sort_by, 1); cZoomQuery = c; } zoom-0.5.0/ext/rbzoompackage.c0000644000004100000410000001212612572455554016340 0ustar www-datawww-data/* * Copyright (C) 2007 Katipo Communications, Ltd. * * This library 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 (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rbzoom.h" #include #ifdef MAKING_RDOC_HAPPY mZoom = rb_define_module("ZOOM"); #endif /* Document-class: ZOOM::Package * * This class represents an Extended Services Package: an instruction to the server * to do something not covered by the core parts of the Z39.50 standard */ static VALUE cZoomPackage; static ZOOM_package rbz_package_get (VALUE obj) { ZOOM_package package; if (cZoomPackage == Qnil) rb_raise(rb_eRuntimeError, "cZoomPackage is nil: has destroy() already been called on this Package?"); Data_Get_Struct (obj, struct ZOOM_package_p, package); assert (package != NULL); return package; } /* * call-seq: * make(connection, options) * * Creates a ZOOM::Package from the connection and options specified. * * Returns: the created ZOOM::Package or Qnil. */ VALUE rbz_package_make (ZOOM_connection connection, ZOOM_options options) { ZOOM_package package; package = ZOOM_connection_package(connection, options); if (cZoomPackage == Qnil) rb_raise(rb_eRuntimeError, "cZoomPackage is nil: has destroy() already been called on this Package?"); return package != NULL ? Data_Wrap_Struct (cZoomPackage, NULL, ZOOM_package_destroy, package) : Qnil; } /* * call-seq: * set_option(key, value) * * key: the name of the option, as a string. * * value: the value of this option (as a string, integer or boolean). * * Sets an option on the package. * * Returns: self. */ static VALUE rbz_package_set_option (VALUE self, VALUE key, VALUE val) { ZOOM_package package; package = rbz_package_get (self); ZOOM_package_option_set (package, RVAL2CSTR (key), RVAL2CSTR (rb_obj_as_string (val))); return self; } /* * call-seq: * get_option(key) * * key: the name of the option, as a string. * * Gets the value of a package's option. * * Returns: the value of the given option, as a string, integer or boolean. */ static VALUE rbz_package_get_option (VALUE self, VALUE key) { ZOOM_package package; const char *value; package = rbz_package_get (self); value = ZOOM_package_option_get (package, RVAL2CSTR (key)); return zoom_option_value_to_ruby_value (value); } /* * call-seq: * send(type) * * type: the actual extended service package type to be sent, as a string. * * Sends the package. * * Returns: self. */ static VALUE rbz_package_send(VALUE self, VALUE type) { ZOOM_package package; const char *typeChar; package = rbz_package_get (self); typeChar = StringValuePtr(type); ZOOM_package_send(package, typeChar); return self; } /* Interface to a subset of the Z39.50 extended services. */ void Init_zoom_package (VALUE mZoom) { VALUE c; c = rb_define_class_under (mZoom, "Package", rb_cObject); /* Remove the default constructor to force initialization through Connection#package. */ rb_undef_method (CLASS_OF (c), "new"); /* Instance methods */ rb_define_method (c, "set_option", rbz_package_set_option, 2); rb_define_method (c, "get_option", rbz_package_get_option, 1); rb_define_method (c, "send", rbz_package_send, 1); // Common Options define_zoom_option (c, "package-name"); define_zoom_option (c, "user-id"); define_zoom_option (c, "function"); define_zoom_option (c, "waitAction"); define_zoom_option (c, "targetReference"); // Item Order, type must be set to itemorder in ZOOM_package_send. define_zoom_option (c, "contact-name"); define_zoom_option (c, "contact-phone"); define_zoom_option (c, "contact-email"); define_zoom_option (c, "itemorder-item"); // Record Update, type must be set to update in ZOOM_package_send. define_zoom_option (c, "action"); define_zoom_option (c, "recordIdOpaque"); define_zoom_option (c, "recordIdNumber"); define_zoom_option (c, "record"); define_zoom_option (c, "syntax"); define_zoom_option (c, "databaseName"); define_zoom_option (c, "correlationInfo.note"); define_zoom_option (c, "correlationInfo.id"); define_zoom_option (c, "elementSetName"); // Database Create, type must be set to create in ZOOM_package_send. // Database Drop, type must be set to drop in ZOOM_package_send. cZoomPackage = c; } zoom-0.5.0/ext/rbzoom.c0000644000004100000410000000205412572455554015023 0ustar www-datawww-data/* * Copyright (C) 2005 Laurent Sansonetti * * This library 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 (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rbzoom.h" void Init_zoom (void) { VALUE mZoom; mZoom = rb_define_module ("ZOOM"); Init_zoom_connection (mZoom); Init_zoom_query (mZoom); Init_zoom_resultset (mZoom); Init_zoom_record (mZoom); Init_zoom_package (mZoom); } zoom-0.5.0/ext/rbzoomoptions.c0000644000004100000410000000636712572455554016452 0ustar www-datawww-data/* * Copyright (C) 2005 Laurent Sansonetti * * This library 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 (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "rbzoom.h" ZOOM_options ruby_hash_to_zoom_options (VALUE hash) { ZOOM_options options; VALUE ary; VALUE pair; VALUE key; VALUE value; int i; options = ZOOM_options_create (); ary = rb_funcall (hash, rb_intern ("to_a"), 0); for (i = 0; i < RARRAY_LEN(ary); i++) { pair = RARRAY_PTR(ary)[i]; key = RARRAY_PTR(pair)[0]; value = RARRAY_PTR(pair)[1]; switch (TYPE (value)) { case T_TRUE: case T_FALSE: ZOOM_options_set_int (options, RVAL2CSTR (key), RVAL2CBOOL (value) ? 1 : 0); break; case T_FIXNUM: ZOOM_options_set_int (options, RVAL2CSTR (key), FIX2INT (value)); break; case T_STRING: ZOOM_options_set (options, RVAL2CSTR (key), RVAL2CSTR (value)); break; default: rb_raise (rb_eArgError, "Unrecognized type"); } } return options; } VALUE zoom_option_value_to_ruby_value (const char *value) { unsigned int i; if (value == NULL) return Qnil; for (i = 0; i < strlen (value); i++) if (!isdigit (value [i])) return CSTR2RVAL (value); return INT2FIX (atoi (value)); } void define_zoom_option (VALUE klass, const char *option) { char code [1024]; char rubyname [128]; char c; unsigned int i; unsigned int j; /* rubyfy the option name */ for (i = 0, j = 0; i < strlen (option) && j < sizeof rubyname; i++, j++) { c = option [i]; if (isupper (c)) { rubyname [j++] = '_'; c = tolower (c); } else if (c == '-') { c = '_'; } else if (c == '.') { c = '_'; } rubyname [j] = c; } rubyname [j] = '\0'; snprintf (code, sizeof code, "def %s; get_option(\"%s\"); end\n" "def %s=(val); set_option(\"%s\", val); val; end\n" "def set_%s(val); set_option(\"%s\", val); end\n", rubyname, option, rubyname, option, rubyname, option); rb_funcall (klass, rb_intern ("module_eval"), 1, CSTR2RVAL (code)); } zoom-0.5.0/ext/rbzoomrecord.c0000644000004100000410000001242012572455554016220 0ustar www-datawww-data/* * Copyright (C) 2005 Laurent Sansonetti * * This library 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 (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rbzoom.h" #ifdef MAKING_RDOC_HAPPY mZoom = rb_define_module("ZOOM"); #endif /* * A record object is a retrieval record on the client side - created from * result sets. */ static VALUE cZoomRecord; VALUE rbz_record_make (ZOOM_record record) { return record != NULL ? Data_Wrap_Struct (cZoomRecord, NULL, ZOOM_record_destroy, record) : Qnil; } static ZOOM_record rbz_record_get (VALUE obj) { ZOOM_record record; Data_Get_Struct (obj, struct ZOOM_record_p, record); assert (record != NULL); return record; } static char _type [128]; static const char * rbz_record_type (const char *form, int argc, VALUE *argv) { VALUE charset_from; VALUE charset_to; if (argc == 0) return form; rb_scan_args (argc, argv, "11", &charset_from, &charset_to); memset (_type, 0, sizeof _type); if (NIL_P (charset_to)) snprintf (_type, sizeof _type, "%s; charset=%s", form, RVAL2CSTR (charset_from)); else snprintf (_type, sizeof _type, "%s; charset=%s,%s", form, RVAL2CSTR (charset_from), RVAL2CSTR (charset_to)); return _type; } /* * call-seq: * database(charset_from=nil, charset_to=nil) * * charset_from: the name of the charset to convert from (optional). * * charset_to: the name of the charset to convert to (optional). * * Returns: the database name of the record. */ static VALUE rbz_record_database (int argc, VALUE *argv, VALUE self) { return CSTR2RVAL (ZOOM_record_get (rbz_record_get (self), rbz_record_type ("database", argc, argv), NULL)); } /* * call-seq: * syntax(charset_from=nil, charset_to=nil) * * charset_from: the name of the charset to convert from (optional). * * charset_to: the name of the charset to convert to (optional). * * Returns: the symbolic transfer syntax name of the record. */ static VALUE rbz_record_syntax (int argc, VALUE *argv, VALUE self) { return CSTR2RVAL (ZOOM_record_get (rbz_record_get (self), rbz_record_type ("syntax", argc, argv), NULL)); } /* * call-seq: * render(charset_from=nil, charset_to=nil) * * charset_from: the name of the charset to convert from (optional). * * charset_to: the name of the charset to convert to (optional). * * Returns: a display friendly description of the record. */ static VALUE rbz_record_render (int argc, VALUE *argv, VALUE self) { return CSTR2RVAL (ZOOM_record_get (rbz_record_get (self), rbz_record_type ("render", argc, argv), NULL)); } /* * call-seq: * xml(charset_from=nil, charset_to=nil) * * charset_from: the name of the charset to convert from (optional). * * charset_to: the name of the charset to convert to (optional). * * Returns an XML description of the record. SRW/SRU and Z39.50 records with * transfer syntax XML are returned verbatim. MARC records are returned in * MARCXML (converted from ISO2709 to MARCXML by YAZ). GRS-1 and OPAC records are * not supported for this form. * * Returns: an XML description of the record. */ static VALUE rbz_record_xml (int argc, VALUE *argv, VALUE self) { return CSTR2RVAL (ZOOM_record_get (rbz_record_get (self), rbz_record_type ("xml", argc, argv), NULL)); } /* * call-seq: * raw * * MARC records are returned in ISO2709. * GRS-1 and OPAC records are not supported for this form. * * Returns: an ISO2709 record. */ static VALUE rbz_record_raw (int argc, VALUE *argv, VALUE self) { return CSTR2RVAL (ZOOM_record_get (rbz_record_get (self), rbz_record_type ("raw", argc, argv), NULL)); } void Init_zoom_record (VALUE mZoom) { VALUE c; c = rb_define_class_under (mZoom, "Record", rb_cObject); rb_undef_method (CLASS_OF (c), "new"); rb_define_method (c, "database", rbz_record_database, -1); rb_define_method (c, "syntax", rbz_record_syntax, -1); rb_define_method (c, "render", rbz_record_render, -1); rb_define_alias (c, "to_s", "render"); rb_define_method (c, "xml", rbz_record_xml, -1); rb_define_method (c, "raw", rbz_record_raw, -1); cZoomRecord = c; } zoom-0.5.0/ext/rbzoomconnection.c0000644000004100000410000002451412572455554017110 0ustar www-datawww-data/* * Copyright (C) 2005 Laurent Sansonetti * * This library 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 (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "rbzoom.h" #ifdef MAKING_RDOC_HAPPY mZoom = rb_define_module("ZOOM"); #endif /* Document-class: ZOOM::Connection * The Connection object is a session with a target. */ static VALUE cZoomConnection; static VALUE rbz_connection_make (ZOOM_connection connection) { return connection != NULL ? Data_Wrap_Struct (cZoomConnection, NULL, ZOOM_connection_destroy, connection) : Qnil; } static ZOOM_connection rbz_connection_get (VALUE obj) { ZOOM_connection connection; Data_Get_Struct (obj, struct ZOOM_connection_p, connection); assert (connection != NULL); return connection; } #define RAISE_IF_FAILED(connection) \ do { \ int error; \ const char *errmsg; \ const char *addinfo; \ \ error = ZOOM_connection_error (connection, \ &errmsg, \ &addinfo); \ if (error != 0) \ rb_raise (rb_eRuntimeError, "%s (%d) %s", \ errmsg, error, addinfo); \ } \ while (0) void rbz_connection_check(VALUE obj) { ZOOM_connection connection; connection = rbz_connection_get(obj); RAISE_IF_FAILED (connection); } /* * call-seq: * open(host, port=nil) { |conn| ... } * * host: hostname of the target to connect to. * * port: network port of the target to connect to. * * A convenience method that creates a new connection and attempts to * establish a network connection to the given target, basically calling * ZOOM::Connection.new and ZOOM::Connection#connect. * * If a block is given, then it will be called once the connection is * established, passing a reference to the connection object as a parameter, * and destroying the connection automatically at the end of the block. * With no block, this method just returns the connection object. * * Returns: a newly created ZOOM::Connection object. */ static VALUE rbz_connection_open (int argc, VALUE *argv, VALUE self) { VALUE host; VALUE port; ZOOM_connection connection; VALUE rb_connection; rb_scan_args (argc, argv, "11", &host, &port); connection = ZOOM_connection_new (RVAL2CSTR (host), NIL_P (port) ? 0 : FIX2INT (port)); RAISE_IF_FAILED (connection); rb_connection = rbz_connection_make (connection); if (rb_block_given_p ()) { rb_yield(rb_connection); return Qnil; } return rb_connection; } /* * call-seq: new(options=nil) * * options: options for the connection, as a Hash object. * * Creates a new connection object, but does not establish a network connection * immediately, allowing you to specify options before (if given). You can * thus establish the connection using ZOOM::Connection#connect. * * Returns: a newly created ZOOM::Connection object. */ static VALUE rbz_connection_new (int argc, VALUE *argv, VALUE self) { ZOOM_options options; ZOOM_connection connection; VALUE rb_options; rb_scan_args (argc, argv, "01", &rb_options); if (NIL_P (rb_options)) options = ZOOM_options_create (); else options = ruby_hash_to_zoom_options (rb_options); connection = ZOOM_connection_create (options); ZOOM_options_destroy (options); RAISE_IF_FAILED (connection); return rbz_connection_make (connection); } /* * call-seq: * connect(host, port=nil) * * host: hostname of the target to connect to. * * port: network port of the target to connect to. * * Establishes a network connection to the target specified by the given * arguments. If no port is given, 210 will be used. A colon in the host * string denotes the beginning of a port number. If the host string includes * a slash, the following part specifies a database for the connection. * * You can also prefix the host string with a scheme followed by a colon. * The default scheme is tcp (Z39.50 protocol). The scheme http selects SRW * over HTTP. * * This method raises an exception on error. * * Returns: self. */ static VALUE rbz_connection_connect (int argc, VALUE *argv, VALUE self) { ZOOM_connection connection; VALUE host; VALUE port; rb_scan_args (argc, argv, "11", &host, &port); connection = rbz_connection_get (self); ZOOM_connection_connect (connection, RVAL2CSTR (host), NIL_P (port) ? 0 : FIX2INT (port)); RAISE_IF_FAILED (connection); return self; } /* * call-seq: * set_option(key, value) * * key: the name of the option, as a string. * * value: the value of this option (as a string, integer or boolean). * * Sets an option on the connection. * * Returns: self. */ static VALUE rbz_connection_set_option (VALUE self, VALUE key, VALUE val) { ZOOM_connection connection; connection = rbz_connection_get (self); ZOOM_connection_option_set (connection, RVAL2CSTR (key), RVAL2CSTR (rb_obj_as_string (val))); RAISE_IF_FAILED (connection); return self; } /* * call-seq: * get_option(key) * * key: the name of the option, as a string. * * Gets the value of a connection's option. * * Returns: the value of the given option, as a string, integer or boolean. */ static VALUE rbz_connection_get_option (VALUE self, VALUE key) { ZOOM_connection connection; const char *value; connection = rbz_connection_get (self); value = ZOOM_connection_option_get (connection, RVAL2CSTR (key)); return zoom_option_value_to_ruby_value (value); } /* * call-seq: * search(criterion) * * criterion: the search criterion, either as a ZOOM::Query object or as a string, * representing a PQF query. * * Searches the connection from the given criterion. You can either create and * pass a reference to a ZOOM::Query object, or you can simply pass a string * that represents a PQF query. * * This method raises an exception on error. * * Returns: a result set from the search, as a ZOOM::ResultSet object, * empty if no results were found. */ static VALUE rbz_connection_search (VALUE self, VALUE criterion) { ZOOM_connection connection; ZOOM_resultset resultset; connection = rbz_connection_get (self); if (TYPE (criterion) == T_STRING) resultset = ZOOM_connection_search_pqf (connection, RVAL2CSTR (criterion)); else resultset = ZOOM_connection_search (connection, rbz_query_get (criterion)); RAISE_IF_FAILED (connection); assert (resultset != NULL); return rbz_resultset_make (resultset); } /* * Constructs a new extended services ZOOM::Package using this connections host information. * * Note: The Perl script passes this connections options if already set, otherwise constructs a new ZOOM::Option object. * Currently this method always constructs a new ZOOM::Option object for each package. * * Returns: a new ZOOM::Package object. */ static VALUE rbz_connection_package(VALUE self) { ZOOM_connection connection; ZOOM_options options; VALUE package; connection = rbz_connection_get (self); options = ZOOM_options_create (); package = rbz_package_make(connection, options); return package; } void Init_zoom_connection (VALUE mZoom) { VALUE c; c = rb_define_class_under (mZoom, "Connection", rb_cObject); rb_define_singleton_method (c, "open", rbz_connection_open, -1); rb_define_singleton_method (c, "new", rbz_connection_new, -1); rb_define_method (c, "connect", rbz_connection_connect, -1); rb_define_method (c, "set_option", rbz_connection_set_option, 2); rb_define_method (c, "get_option", rbz_connection_get_option, 1); rb_define_method (c, "package", rbz_connection_package, 0); define_zoom_option (c, "implementationName"); define_zoom_option (c, "user"); define_zoom_option (c, "group"); define_zoom_option (c, "password"); define_zoom_option (c, "host"); define_zoom_option (c, "proxy"); define_zoom_option (c, "async"); define_zoom_option (c, "maximumRecordSize"); define_zoom_option (c, "preferredMessageSize"); define_zoom_option (c, "lang"); define_zoom_option (c, "charset"); define_zoom_option (c, "serverImplementationId"); define_zoom_option (c, "targetImplementationName"); define_zoom_option (c, "serverImplementationVersion"); define_zoom_option (c, "databaseName"); define_zoom_option (c, "piggyback"); define_zoom_option (c, "smallSetUpperBound"); define_zoom_option (c, "largeSetLowerBound"); define_zoom_option (c, "mediumSetPresentNumber"); define_zoom_option (c, "smallSetElementSetName"); define_zoom_option (c, "mediumSetElementSetName"); /* herited from Zoom::ResultSet */ define_zoom_option (c, "start"); define_zoom_option (c, "count"); define_zoom_option (c, "presentChunk"); define_zoom_option (c, "elementSetName"); define_zoom_option (c, "preferredRecordSyntax"); define_zoom_option (c, "schema"); define_zoom_option (c, "setname"); rb_define_method (c, "search", rbz_connection_search, 1); cZoomConnection = c; } zoom-0.5.0/ext/rbzoom.h0000644000004100000410000000406512572455554015034 0ustar www-datawww-data/* * Copyright (C) 2005 Laurent Sansonetti * * This library 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 (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __RBZOOM_H_ #define __RBZOOM_H_ #include #include #include /* initialization */ void Init_zoom (void); void Init_zoom_connection (VALUE mZoom); void Init_zoom_query (VALUE mZoom); void Init_zoom_resultset (VALUE mZoom); void Init_zoom_record (VALUE mZoom); void Init_zoom_package (VALUE mZoom); /* rbzoomoptions.c */ ZOOM_options ruby_hash_to_zoom_options (VALUE hash); VALUE zoom_option_value_to_ruby_value (const char *value); void define_zoom_option (VALUE klass, const char *option); /* rbzoomparse.c */ ZOOM_query rbz_query_get (VALUE obj); /* rbzoomresultset.c */ VALUE rbz_resultset_make (ZOOM_resultset resultset); /* rbzoomrecord.c */ VALUE rbz_record_make (ZOOM_record record); /* rbzoompackage.c */ VALUE rbz_package_make (ZOOM_connection connection, ZOOM_options options); /* rbconnection.c */ void rbz_connection_check(VALUE obj); /* useful macros */ #if !defined (RVAL2CSTR) # define RVAL2CSTR(x) (NIL_P (x) ? NULL : RSTRING_PTR(x)) #endif #if !defined (CSTR2RVAL) # define CSTR2RVAL(x) (x == NULL ? Qnil : rb_str_new2(x)) #endif #if !defined (RVAL2CBOOL) # define RVAL2CBOOL(x) (RTEST (x)) #endif #if !defined (CBOOL2RVAL) # define CBOOL2RVAL(x) (x ? Qtrue : Qfalse) #endif #endif /* __RBZOOM_H_ */ zoom-0.5.0/README.md0000644000004100000410000000520412572455554014026 0ustar www-datawww-dataRuby/ZOOM ========= Ruby/ZOOM provides a Ruby binding to the Z39.50 Object-Orientation Model (ZOOM), an abstract object-oriented programming interface to a subset of the services specified by the Z39.50 standard, also known as the international standard ISO 23950. This software is based (and therefore depends) on YAZ, a free-software implementation of the Z39.50/SRW/SRU standards, but could be easily ported to any ZOOM compliant implementation. Ruby/ZOOM is free-software, covered by the GNU Lesser General Public License and provided without any warranties of any kind. Requirements ------------ Ruby: http://www.ruby-lang.org/ YAZ (*): http://www.indexdata.dk/yaz/ * : Make sure you did pass the --enabled-shared option to the configure script before building YAZ. Ruby/ZOOM requires a YAZ shared library and YAZ does not build it by default. Build from Source ------- 0. checkout out code from git at github 1. install Rake 2. rake 3. gem install pkg/zoom-*.gem Build from Source using bundler ----------------- 0. add to your Gemfile: gem 'zoom', :git => 'https://github.com/bricestacey/ruby-zoom.git' 1. bundle Samples ------- Some programming examples are available in the `sample' directory. Canonical Sample Program ------------------------ To give a flavour of the Ruby binding, here is ZOOM's equivalent of the ``Hello World'' program: a tiny Z39.50 client that fetches and displays the MARC record for Farlow & Brett Surman's The Complete Dinosaur from the Library of Congress. require 'zoom' ZOOM::Connection.open('z3950.loc.gov', 7090) do |conn| conn.database_name = 'Voyager' conn.preferred_record_syntax = 'USMARC' rset = conn.search('@attr 1=7 0253333490') p rset[0] end ZOOM Extended Services ---------------------- With release 0.4.1 extended services support has been added which allows create, update and delete of records. This only works for XML. Here's an example adapted from the test suite. require 'zoom' new_record = File.read('programming_ruby.xml') ZOOM::Connection.open('localhost:99999/test') do |conn| p = conn.package p.wait_action = 'waitIfPossible' p.action = 'specialUpdate' p.record = new_record p.send('update') p.send('commit') end Copying ------- Copyright (c) 2005 Laurent Sansonetti This library is free software. You can distribute/modify this program under the terms of the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1. Project Website --------------- http://ruby-zoom.rubyforge.org