zoom 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,61 @@
1
+ /*
2
+ * Copyright (C) 2005 Laurent Sansonetti <lrz@chopine.be>
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2.1 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ */
18
+
19
+ #ifndef __RBZOOM_H_
20
+ #define __RBZOOM_H_
21
+
22
+ #include <yaz/zoom.h>
23
+ #include <ruby.h>
24
+ #include <assert.h>
25
+
26
+ /* initialization */
27
+ void Init_zoom (void);
28
+ void Init_zoom_connection (VALUE mZoom);
29
+ void Init_zoom_query (VALUE mZoom);
30
+ void Init_zoom_resultset (VALUE mZoom);
31
+ void Init_zoom_record (VALUE mZoom);
32
+
33
+ /* rbzoomoptions.c */
34
+ ZOOM_options ruby_hash_to_zoom_options (VALUE hash);
35
+ VALUE zoom_option_value_to_ruby_value (const char *value);
36
+ void define_zoom_option (VALUE klass, const char *option);
37
+
38
+ /* rbzoomparse.c */
39
+ ZOOM_query rbz_query_get (VALUE obj);
40
+
41
+ /* rbzoomresultset.c */
42
+ VALUE rbz_resultset_make (ZOOM_resultset resultset);
43
+
44
+ /* rbzoomrecord.c */
45
+ VALUE rbz_record_make (ZOOM_record record);
46
+
47
+ /* useful macros */
48
+ #if !defined (RVAL2CSTR)
49
+ # define RVAL2CSTR(x) (NIL_P (x) ? NULL : STR2CSTR(x))
50
+ #endif
51
+ #if !defined (CSTR2RVAL)
52
+ # define CSTR2RVAL(x) (x == NULL ? Qnil : rb_str_new2(x))
53
+ #endif
54
+ #if !defined (RVAL2CBOOL)
55
+ # define RVAL2CBOOL(x) (RTEST (x))
56
+ #endif
57
+ #if !defined (CBOOL2RVAL)
58
+ # define CBOOL2RVAL(x) (x ? Qtrue : Qfalse)
59
+ #endif
60
+
61
+ #endif /* __RBZOOM_H_ */
@@ -0,0 +1,291 @@
1
+ /*
2
+ * Copyright (C) 2005 Laurent Sansonetti <lrz@chopine.be>
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2.1 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ */
18
+
19
+ #include "rbzoom.h"
20
+
21
+ /* Class: ZOOM::Connection
22
+ * The Connection object is a session with a target.
23
+ */
24
+ static VALUE cZoomConnection;
25
+
26
+ static VALUE
27
+ rbz_connection_make (ZOOM_connection connection)
28
+ {
29
+ return connection != NULL
30
+ ? Data_Wrap_Struct (cZoomConnection,
31
+ NULL,
32
+ ZOOM_connection_destroy,
33
+ connection)
34
+ : Qnil;
35
+ }
36
+
37
+ static ZOOM_connection
38
+ rbz_connection_get (VALUE obj)
39
+ {
40
+ ZOOM_connection connection;
41
+
42
+ Data_Get_Struct (obj, struct ZOOM_connection_p, connection);
43
+ assert (connection != NULL);
44
+
45
+ return connection;
46
+ }
47
+
48
+ #define RAISE_IF_FAILED(connection) \
49
+ do { \
50
+ int error; \
51
+ const char *errmsg; \
52
+ const char *addinfo; \
53
+ \
54
+ error = ZOOM_connection_error (connection, \
55
+ &errmsg, \
56
+ &addinfo); \
57
+ if (error != 0) \
58
+ rb_raise (rb_eRuntimeError, "%s (%d) %s", \
59
+ errmsg, error, addinfo); \
60
+ } \
61
+ while (0)
62
+
63
+ /*
64
+ * Class method: open(host, port=nil) { |conn| ... }
65
+ * host: hostname of the target to connect to.
66
+ * port: network port of the target to connect to.
67
+ *
68
+ * A convenience method that creates a new connection and attempts to
69
+ * establish a network connection to the given target, basically calling
70
+ * ZOOM::Connection.new and ZOOM::Connection#connect.
71
+ *
72
+ * If a block is given, then it will be called once the connection is
73
+ * established, passing a reference to the connection object as a parameter,
74
+ * and destroying the connection automatically at the end of the block.
75
+ * With no block, this method just returns the connection object.
76
+ *
77
+ * Returns: a newly created ZOOM::Connection object.
78
+ */
79
+ static VALUE
80
+ rbz_connection_open (int argc, VALUE *argv, VALUE self)
81
+ {
82
+ VALUE host;
83
+ VALUE port;
84
+ ZOOM_connection connection;
85
+ VALUE rb_connection;
86
+
87
+ rb_scan_args (argc, argv, "11", &host, &port);
88
+
89
+ connection = ZOOM_connection_new (RVAL2CSTR (host),
90
+ NIL_P (port) ? 0 : FIX2INT (port));
91
+ RAISE_IF_FAILED (connection);
92
+
93
+ rb_connection = rbz_connection_make (connection);
94
+ if (rb_block_given_p ()) {
95
+ rb_yield(rb_connection);
96
+ return Qnil;
97
+ }
98
+ return rb_connection;
99
+ }
100
+
101
+ /*
102
+ * Class method: new(options=nil)
103
+ * options: options for the connection, as a Hash object.
104
+ *
105
+ * Creates a new connection object, but does not establish a network connection
106
+ * immediately, allowing you to specify options before (if given). You can
107
+ * thus establish the connection using ZOOM::Connection#connect.
108
+ *
109
+ * Returns: a newly created ZOOM::Connection object.
110
+ */
111
+ static VALUE
112
+ rbz_connection_new (int argc, VALUE *argv, VALUE self)
113
+ {
114
+ ZOOM_options options;
115
+ ZOOM_connection connection;
116
+ VALUE rb_options;
117
+
118
+ rb_scan_args (argc, argv, "01", &rb_options);
119
+
120
+ if (NIL_P (rb_options))
121
+ options = ZOOM_options_create ();
122
+ else
123
+ options = ruby_hash_to_zoom_options (rb_options);
124
+
125
+ connection = ZOOM_connection_create (options);
126
+ ZOOM_options_destroy (options);
127
+ RAISE_IF_FAILED (connection);
128
+
129
+ return rbz_connection_make (connection);
130
+ }
131
+
132
+ /*
133
+ * Method: connect(host, port=nil)
134
+ * host: hostname of the target to connect to.
135
+ * port: network port of the target to connect to.
136
+ *
137
+ * Establishes a network connection to the target specified by the given
138
+ * arguments. If no port is given, 210 will be used. A colon in the host
139
+ * string denotes the beginning of a port number. If the host string includes
140
+ * a slash, the following part specifies a database for the connection.
141
+ *
142
+ * You can also prefix the host string with a scheme followed by a colon.
143
+ * The default scheme is tcp (Z39.50 protocol). The scheme http selects SRW
144
+ * over HTTP.
145
+ *
146
+ * This method raises an exception on error.
147
+ *
148
+ * Returns: self.
149
+ */
150
+ static VALUE
151
+ rbz_connection_connect (int argc, VALUE *argv, VALUE self)
152
+ {
153
+ ZOOM_connection connection;
154
+ VALUE host;
155
+ VALUE port;
156
+
157
+ rb_scan_args (argc, argv, "11", &host, &port);
158
+
159
+ connection = rbz_connection_get (self);
160
+ ZOOM_connection_connect (connection,
161
+ RVAL2CSTR (host),
162
+ NIL_P (port) ? 0 : FIX2INT (port));
163
+ RAISE_IF_FAILED (connection);
164
+
165
+ return self;
166
+ }
167
+
168
+ /*
169
+ * Method: set_option(key, value)
170
+ * key: the name of the option, as a string.
171
+ * value: the value of this option (as a string, integer or boolean).
172
+ *
173
+ * Sets an option on the connection.
174
+ *
175
+ * Returns: self.
176
+ */
177
+ static VALUE
178
+ rbz_connection_set_option (VALUE self, VALUE key, VALUE val)
179
+ {
180
+ ZOOM_connection connection;
181
+
182
+ connection = rbz_connection_get (self);
183
+ ZOOM_connection_option_set (connection,
184
+ RVAL2CSTR (key),
185
+ RVAL2CSTR (rb_obj_as_string (val)));
186
+ RAISE_IF_FAILED (connection);
187
+
188
+ return self;
189
+ }
190
+
191
+ /*
192
+ * Method: get_option(key)
193
+ * key: the name of the option, as a string.
194
+ *
195
+ * Gets the value of a connection's option.
196
+ *
197
+ * Returns: the value of the given option, as a string, integer or boolean.
198
+ */
199
+ static VALUE
200
+ rbz_connection_get_option (VALUE self, VALUE key)
201
+ {
202
+ ZOOM_connection connection;
203
+ const char *value;
204
+
205
+ connection = rbz_connection_get (self);
206
+ value = ZOOM_connection_option_get (connection,
207
+ RVAL2CSTR (key));
208
+
209
+ return zoom_option_value_to_ruby_value (value);
210
+ }
211
+
212
+ /*
213
+ * Method: search(criterion)
214
+ * criterion: the search criterion, either as a ZOOM::Query object or as a string,
215
+ * representing a PQF query.
216
+ *
217
+ * Searches the connection from the given criterion. You can either create and
218
+ * pass a reference to a ZOOM::Query object, or you can simply pass a string
219
+ * that represents a PQF query.
220
+ *
221
+ * This method raises an exception on error.
222
+ *
223
+ * Returns: a result set from the search, as a ZOOM::ResultSet object,
224
+ * empty if no results were found.
225
+ */
226
+ static VALUE
227
+ rbz_connection_search (VALUE self, VALUE criterion)
228
+ {
229
+ ZOOM_connection connection;
230
+ ZOOM_resultset resultset;
231
+
232
+ connection = rbz_connection_get (self);
233
+ if (TYPE (criterion) == T_STRING)
234
+ resultset = ZOOM_connection_search_pqf (connection,
235
+ RVAL2CSTR (criterion));
236
+ else
237
+ resultset = ZOOM_connection_search (connection,
238
+ rbz_query_get (criterion));
239
+ RAISE_IF_FAILED (connection);
240
+ assert (resultset != NULL);
241
+
242
+ return rbz_resultset_make (resultset);
243
+ }
244
+
245
+ void
246
+ Init_zoom_connection (VALUE mZoom)
247
+ {
248
+ VALUE c;
249
+
250
+ c = rb_define_class_under (mZoom, "Connection", rb_cObject);
251
+ rb_define_singleton_method (c, "open", rbz_connection_open, -1);
252
+ rb_define_singleton_method (c, "new", rbz_connection_new, -1);
253
+ rb_define_method (c, "connect", rbz_connection_connect, -1);
254
+ rb_define_method (c, "set_option", rbz_connection_set_option, 2);
255
+ rb_define_method (c, "get_option", rbz_connection_get_option, 1);
256
+
257
+ define_zoom_option (c, "implementationName");
258
+ define_zoom_option (c, "user");
259
+ define_zoom_option (c, "group");
260
+ define_zoom_option (c, "password");
261
+ define_zoom_option (c, "host");
262
+ define_zoom_option (c, "proxy");
263
+ define_zoom_option (c, "async");
264
+ define_zoom_option (c, "maximumRecordSize");
265
+ define_zoom_option (c, "preferredMessageSize");
266
+ define_zoom_option (c, "lang");
267
+ define_zoom_option (c, "charset");
268
+ define_zoom_option (c, "serverImplementationId");
269
+ define_zoom_option (c, "targetImplementationName");
270
+ define_zoom_option (c, "serverImplementationVersion");
271
+ define_zoom_option (c, "databaseName");
272
+ define_zoom_option (c, "piggyback");
273
+ define_zoom_option (c, "smallSetUpperBound");
274
+ define_zoom_option (c, "largeSetLowerBound");
275
+ define_zoom_option (c, "mediumSetPresentNumber");
276
+ define_zoom_option (c, "smallSetElementSetName");
277
+ define_zoom_option (c, "mediumSetElementSetName");
278
+
279
+ /* herited from Zoom::ResultSet */
280
+ define_zoom_option (c, "start");
281
+ define_zoom_option (c, "count");
282
+ define_zoom_option (c, "presentChunk");
283
+ define_zoom_option (c, "elementSetName");
284
+ define_zoom_option (c, "preferredRecordSyntax");
285
+ define_zoom_option (c, "schema");
286
+ define_zoom_option (c, "setname");
287
+
288
+ rb_define_method (c, "search", rbz_connection_search, 1);
289
+
290
+ cZoomConnection = c;
291
+ }
@@ -0,0 +1,112 @@
1
+ /*
2
+ * Copyright (C) 2005 Laurent Sansonetti <lrz@chopine.be>
3
+ *
4
+ * This library is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU Lesser General Public
6
+ * License as published by the Free Software Foundation; either
7
+ * version 2.1 of the License, or (at your option) any later version.
8
+ *
9
+ * This library is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ * Lesser General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Lesser General Public
15
+ * License along with this library; if not, write to the Free Software
16
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
+ */
18
+
19
+ #include <ctype.h>
20
+ #include "rbzoom.h"
21
+
22
+ ZOOM_options
23
+ ruby_hash_to_zoom_options (VALUE hash)
24
+ {
25
+ ZOOM_options options;
26
+ VALUE ary;
27
+ VALUE pair;
28
+ VALUE key;
29
+ VALUE value;
30
+ int i;
31
+
32
+ options = ZOOM_options_create ();
33
+
34
+ ary = rb_funcall (hash, rb_intern ("to_a"), 0);
35
+ for (i = 0; i < RARRAY (ary)->len; i++) {
36
+ pair = RARRAY (ary)->ptr[i];
37
+ key = RARRAY (pair)->ptr[0];
38
+ value = RARRAY (pair)->ptr[1];
39
+
40
+ switch (TYPE (value)) {
41
+ case T_TRUE:
42
+ case T_FALSE:
43
+ ZOOM_options_set_int (options,
44
+ RVAL2CSTR (key),
45
+ RVAL2CBOOL (value) ? 1 : 0);
46
+ break;
47
+
48
+ case T_FIXNUM:
49
+ ZOOM_options_set_int (options,
50
+ RVAL2CSTR (key),
51
+ FIX2INT (value));
52
+ break;
53
+
54
+ case T_STRING:
55
+ ZOOM_options_set (options,
56
+ RVAL2CSTR (key),
57
+ RVAL2CSTR (value));
58
+ break;
59
+
60
+ default:
61
+ rb_raise (rb_eArgError, "Unrecognized type");
62
+ }
63
+ }
64
+
65
+ return options;
66
+ }
67
+
68
+ VALUE
69
+ zoom_option_value_to_ruby_value (const char *value)
70
+ {
71
+ int i;
72
+
73
+ if (value == NULL)
74
+ return Qnil;
75
+
76
+ for (i = 0; i < strlen (value); i++)
77
+ if (!isdigit (value [i]))
78
+ return CSTR2RVAL (value);
79
+
80
+ return INT2FIX (atoi (value));
81
+ }
82
+
83
+ void
84
+ define_zoom_option (VALUE klass, const char *option)
85
+ {
86
+ char code [1024];
87
+ char rubyname [128];
88
+ char c;
89
+ int i;
90
+ int j;
91
+
92
+ /* rubyfy the option name */
93
+ for (i = 0, j = 0; i < strlen (option) && j < sizeof rubyname; i++, j++) {
94
+ c = option [i];
95
+ if (isupper (c)) {
96
+ rubyname [j++] = '_';
97
+ c = tolower (c);
98
+ }
99
+ rubyname [j] = c;
100
+ }
101
+ rubyname [j] = '\0';
102
+
103
+ snprintf (code, sizeof code,
104
+ "def %s; get_option(\"%s\"); end\n"
105
+ "def %s=(val); set_option(\"%s\", val); val; end\n"
106
+ "def set_%s(val); set_option(\"%s\", val); end\n",
107
+ rubyname, option,
108
+ rubyname, option,
109
+ rubyname, option);
110
+
111
+ rb_funcall (klass, rb_intern ("module_eval"), 1, CSTR2RVAL (code));
112
+ }