source: branches/z3950-branch/gsdl/src/recpt/z3950server.cpp@ 1191

Last change on this file since 1191 was 1191, checked in by johnmcp, 24 years ago

Checkpoint: z39.50 collections can now connect and query (and show query
results). Todo: get individual documents, and get working under fast-cgi.

  • Property svn:keywords set to Author Date Id Revision
File size: 5.0 KB
Line 
1#include "z3950server.h"
2#include "comtypes.h"
3#include <stdio.h>
4// z39.50 yaz stuff
5
6extern "C" {
7#include "yaz/client/yaz_zclient.h"
8}
9
10/***
11 each z39.50 server+database pair is a GSDL collection.
12***/
13
14z3950_server::z3950_server() {
15 info=NULL;
16 connected=false;
17 titles=NULL;
18 // for now, assume that all records will have text associated with them.
19 meta["hastxt"]="1";
20}
21
22z3950_server::~z3950_server() {
23}
24
25void z3950_server::setMeta(const text_t &key, const text_t &value) {
26 meta[key]=value;
27}
28
29void z3950_server::setName(const text_t &newname) {
30 title=newname;
31 meta["collectionname"]=newname;
32}
33
34void z3950_server::addcfgAbout(const text_t &lang, const text_t &abouttext) {
35 about[lang]=abouttext;
36}
37
38bool z3950_server::getcfgAbout(const text_t &lang, text_t &abouttxt) {
39 text_tmap::iterator it;
40 it=about.find(lang);
41 if (it==about.end()) return (false);
42 abouttxt=((*it).second);
43 return (true);
44}
45
46
47// now functions that actually talk over the tcp connection.
48
49// create a tcp connection to the associated target. Currently, this will
50// re-initialise if we are already connected.
51bool z3950_server::connect() {
52 text_t server_and_port;
53 char *zserverinfo;
54
55 server_and_port=info->host+":"+info->port;
56 // remember that info.name is the database name
57
58 z_initialize();
59
60 if (z_cmd_open(server_and_port.getcstr(),info->name.getcstr())==1)
61 // we got a connection error
62 return false;
63
64 // get initialisation response.
65 z_getnextAPDU();
66 zserverinfo=z_get_initResponse();
67 if (zserverinfo!=NULL) {
68 z_initstr.appendcstr(zserverinfo);
69 }
70 free(zserverinfo);
71
72 connected=true;
73 return true;
74}
75
76text_tarray *z3950_server::getbriefrecords(const text_t &query,
77 int first, int count,
78 int *nummatches, comerror_t &err) {
79 char **c_str_titles;
80 int i;
81 int last;
82 if (titles!=NULL) delete (titles);
83 titles=new text_tarray;
84
85 if (connected==false)
86 if (connect()==false) {
87 // we could not connect.
88 err=protocolError;
89 return (NULL);
90 }
91
92
93 // We need to format the query string into RPN -
94 // by just passing it like this, it will only work for simple queries.
95 /* check if connected */
96 /* titles->push_back("first dummy title");
97 titles->push_back("Second dummy title");
98 return titles;
99 */
100 // following functions defined in yaz_zclient.c
101 *nummatches=z_cmd_dosearch(query.getcstr()); // returns # found, -1 on err.
102 // could just check if (*nummatches)==0.
103
104 // could do a sort eventually, eg on date, title, etc.
105 // (non-existent function) z_sort(field, asc|desc);
106 /* min of (count, first + (*nummatches) ) */
107 c_str_titles=z_getbriefrecords(first,count);
108 if (c_str_titles==NULL) {
109 // an error occurred. we need a logout/err as an arg
110 return (NULL);
111 }
112 if (c_str_titles[0]==0) {
113 // no matches.
114 return (NULL);
115 }
116 last=(int)c_str_titles[0];
117 for (i=1;i<=last;i++) {
118 titles->push_back(c_str_titles[i]);
119 free(c_str_titles[i]);
120 }
121 free(c_str_titles);
122 return (titles);
123
124}
125
126bool z3950_server::getfullrecord(const int ID, text_t &rettitle,
127 text_t &rettext, comerror_t &err) {
128 if (connected==false) {
129 if (connect()==false) {
130 // error connecting...
131 err=protocolError;
132 return (false);
133 }
134 // since we have just re-connected, we need to do the
135 // query again.
136 }
137
138 if (rettitle!="unneeded") {
139 /*char **c_str_titles;
140 int dummy;
141 c_str_titles=z_getbriefrecords("the",ID,1,&dummy); // check this return value.
142 if (c_str_titles!=NULL && (int)c_str_titles[0]==1) {
143 rettitle.setcstr(c_str_titles[1]); // and check this
144 free (c_str_titles);
145 */
146 // rettitle=(*titles)[ID]; // this isn't quite right, as ID isn't the offset
147 rettitle="Dummy Title";
148 }
149
150 if (rettext!="unneeded") {
151 // get the text
152 rettext="Dummy Text. This is here as a placeholder until I work out";
153 rettext+=" a way to get the query again when running in simple cgi\n";
154 rettext+="as after each page is completed, the connection is lost to the";
155 rettext+=" server, and we forget what the query was\n";
156 }
157 return (true);
158}
159
160text_t &z3950_server::getzAbout() {
161 text_t zserverresp;
162
163 // Assume we have not yet connected, so that must be done here.
164 if (connected==true)
165 return (z_initstr);
166
167 // we need to create the tcp connection to the target (server)
168 // z_initstr=new text_t;
169
170 if (connect()==false) {
171 z_initstr.setcstr("<H2>Server offline</H2>Error - could not connect to server <B>");
172 z_initstr += info->host.getcstr();
173 z_initstr += "</B> on port ";
174 z_initstr += info->port;
175 z_initstr += "\n";
176 return (z_initstr);
177 }
178
179 // z_initstr currently contains the target's response. We want to
180 // PREPEND the following information.
181 zserverresp=z_initstr;
182 z_initstr="Internet server: <b>";
183 z_initstr+=info->host;
184 z_initstr+="</b> on port ";
185 z_initstr+=info->port;
186 z_initstr+=".<br>\n";
187 z_initstr+=zserverresp;
188
189 // should close /******* WHAT IF DOING A QUERY!??!?!? ********/
190 // z_cmd_close(0);
191 // connected=false;
192 return (z_initstr);
193}
194
Note: See TracBrowser for help on using the repository browser.