1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #ifndef _hpp_vdb_cursor_
28 #define _hpp_vdb_cursor_
29 
30 #ifndef _h_vdb_cursor_
31 #include <vdb/cursor.h>
32 #endif
33 
34 
35 /*--------------------------------------------------------------------------
36  * VCursor
37  *  a row cursor onto a VTable
38  */
39 struct VCursor
40 {
41     /* AddRef
42      * Release
43      *  all objects are reference counted
44      *  NULL references are ignored
45      */
AddRefVCursor46     inline rc_t AddRef () const throw()
47     { return VCursorAddRef ( this ); }
48 
ReleaseVCursor49     inline rc_t Release () const throw()
50     { return VCursorRelease ( this ); }
51 
52 
53     /* AddColumn
54      *  add a column to an unopened cursor
55      *
56      *  "idx" [ OUT ] - return parameter for column index
57      *
58      *  "name" [ IN ] - NUL terminated column name spec.
59      *  to identify a column by name, provide the column name
60      *  by itself. if there are multiple types available under
61      *  that name, the default type for that column will be
62      *  selected. to select a specific type, the name may
63      *  be cast to that type using a cast expression, e.g.
64      *    "( type ) name"
65      *  the special name "*" may be added to a read cursor.
66      */
AddColumnVCursor67     inline rc_t AddColumn ( uint32_t *idx,
68         const char *name, ... ) const throw()
69     {
70         va_list args;
71         va_start ( args, name );
72         rc_t rc = VCursorVAddColumn ( this, idx, name, args );
73         va_end ( args );
74         return rc;
75     }
AddColumnVCursor76     inline rc_t AddColumn ( uint32_t *idx,
77         const char *name, va_list args ) const throw()
78     { return VCursorVAddColumn ( this, idx, name, args ); }
79 
80 
81     /* GetColumnIdx
82      *  retrieve column index by name spec
83      *
84      *  "idx" [ OUT ] - return parameter for column index
85      *
86      *  "name" [ IN ] - NUL terminated column name spec.
87      */
GetColumnIdxVCursor88     inline rc_t GetColumnIdx ( uint32_t *idx,
89         const char *name, ... ) const throw()
90     {
91         va_list args;
92         va_start ( args, name );
93         rc_t rc = VCursorVGetColumnIdx ( this, idx, name, args );
94         va_end ( args );
95         return rc;
96     }
GetColumnIdxVCursor97     inline rc_t GetColumnIdx ( uint32_t *idx,
98         const char *name, va_list args ) const throw()
99     { return  VCursorVGetColumnIdx ( this, idx, name, args ); }
100 
101 
102     /* Datatype
103      *  returns typedecl and/or typedef for column data
104      *
105      *  "idx" [ IN ] - column index
106      *
107      *  "type" [ OUT, NULL OKAY ] - returns the column type declaration
108      *
109      *  "def" [ OUT, NULL OKAY ] - returns the definition of the type
110      *  returned in "type_decl"
111      *
112      * NB - one of "type" and "def" must be non-NULL
113      */
DatatypeVCursor114     inline rc_t Datatype ( uint32_t idx, VTypedecl *type,
115         VTypedesc *desc ) const throw()
116     { return VCursorDatatype ( this, idx, type, desc ); }
117 
118 
119     /* IdRange
120      *  returns id range for column
121      *
122      *  "idx" [ IN, OPTIONAL ] - single column index or
123      *  zero to indicate the range for all columns in cursor
124      *
125      *  "id" [ IN ] - page containing this row id is target
126      *
127      *  "first" [ OUT, NULL OKAY ] and "last" [ OUT, NULL OKAY ] -
128      *  id range is returned in these output parameters, where
129      *  at least ONE must be NOT-NULL
130      */
IdRangeVCursor131     inline rc_t IdRange ( int64_t *first, uint64_t *count ) const throw()
132     { return VCursorIdRange ( this, 0, first, count ); }
133 
IdRangeVCursor134     inline rc_t IdRange ( uint32_t idx, int64_t *first,
135         uint64_t *count ) const throw()
136     { return VCursorIdRange ( this, idx, first, count ); }
137 
138 
139     /* Open
140      *  open cursor, resolving schema for the set of opened columns
141      *
142      *  when cursor is created for read, its initial row id
143      *  is set to first row available in any contained column.
144      *
145      *  when cursor is created for write, its initial row id
146      *  is set for inserts ( appending ). when empty, initial
147      *  row id is set to 1. otherwise, it is set to 1 beyond
148      *  the last row available in any contained column.
149      *
150      *  NB - there is no corresponding "Close"
151      *  use "Release" instead.
152      */
OpenVCursor153     inline rc_t Open () const throw()
154     { return VCursorOpen ( this ); }
155 
156 
157     /* RowId
158      *  report current row id
159      * SetRowId
160      *  seek to given row id
161      */
RowIdVCursor162     inline rc_t RowId ( int64_t *row_id ) const throw()
163     { return VCursorRowId ( this, row_id ); }
164 
SetRowIdVCursor165     inline rc_t SetRowId ( int64_t row_id ) const throw()
166     { return VCursorSetRowId ( this, row_id ); }
167 
168 
169     /* OpenRow
170      *  open currently closed row indicated by row id
171      */
OpenRowVCursor172     inline rc_t OpenRow () const throw()
173     { return VCursorOpenRow ( this ); }
174 
175 
176     /* CommitRow
177      *  commit row after writing
178      *  prevents further writes
179      */
CommitRowVCursor180     inline rc_t CommitRow () throw()
181     { return VCursorCommitRow ( this ); }
182 
183 
184     /* CloseRow
185      *  balances OpenRow message
186      *  if there are uncommitted modifications,
187      *  discard all changes. otherwise,
188      *  advance to next row
189      */
CloseRowVCursor190     inline rc_t CloseRow () const throw()
191     { return VCursorCloseRow ( this ); }
192 
193 
194     /* FlushPage
195      *  forces flush of all buffered page data
196      *  fails if row is open
197      *
198      *  pages are normally auto-committed based upon
199      *  size and column affinity
200      */
FlushPageVCursor201     inline rc_t FlushPage () throw()
202     { return VCursorFlushPage ( this ); }
203 
204 
205     /* Read
206      *  read entire single row of byte-aligned data into a buffer
207      *
208      *  "col_idx" [ IN ] - index of column to be read, returned by "AddColumn"
209      *
210      *  "elem_bits" [ IN ] - expected element size in bits, required
211      *  to be compatible with the actual element size, and be a multiple
212      *  of 8 ( byte-aligned ). for non-byte-aligned data, see ReadBits
213      *
214      *  "buffer" [ OUT ] and "blen" [ IN ] - return buffer for row data
215      *  where "blen" gives buffer capacity in elements. the total buffer
216      *  size in bytes == ( "elem_bits" * "blen" + 7 ) / 8.
217      *
218      *  "row_len" [ OUT ] - return parameter for the number of elements
219      *  in the requested row.
220      *
221      *  when the return code is 0, "row_len" will contain the number of
222      *  elements read into buffer. if the return code indicates that the
223      *  buffer is too small, "row_len" will give the required buffer length.
224      */
ReadVCursor225     inline rc_t Read ( uint32_t col_idx, uint32_t elem_bits,
226         void *buffer, uint32_t blen, uint32_t *row_len ) const throw()
227     {
228         return VCursorRead ( this, col_idx, elem_bits, buffer, blen,  row_len );
229     }
ReadVCursor230     inline rc_t Read ( int64_t row_id, uint32_t col_idx, uint32_t elem_bits,
231         void *buffer, uint32_t blen, uint32_t *row_len ) const throw()
232     {
233         return VCursorReadDirect ( this, row_id, col_idx, elem_bits, buffer, blen, row_len );
234     }
235 
236 
237     /* ReadBits
238      *  read single row of potentially bit-aligned column data into a buffer
239      *
240      *  "col_idx" [ IN ] - index of column to be read, returned by "AddColumn"
241      *
242      *  "elem_bits" [ IN ] - expected element size in bits, required to be
243      *  compatible with the actual element size, and may ( or may not ) be
244      *  a multiple of 8 ( byte aligned ).
245      *
246      *  "start" [ IN ] - zero-based starting index to first element,
247      *  valid from 0 .. row_len - 1
248      *
249      *  "buffer" [ IN ], "boff" [ IN ] and "blen" [ IN ] -
250      *  return buffer for row data, where "boff" is in BITS
251      *  and "blen" is in ELEMENTS.
252      *
253      *  "num_read" [ OUT ] - return parameter for the number of elements
254      *  read, which is <= "blen"
255      *
256      *  "remaining" [ OUT, NULL OKAY ] - optional return parameter for
257      *  the number of elements remaining to be read. specifically,
258      *  "start" + "num_read" + "remaining" == row length, assuming that
259      *  "start" <= row length.
260      */
ReadBitsVCursor261     inline rc_t ReadBits ( const VCursor *self, uint32_t col_idx,
262         uint32_t elem_bits, uint32_t start, void *buffer, uint32_t boff,
263         uint32_t blen, uint32_t *num_read, uint32_t *remaining ) const throw()
264     {
265         return VCursorReadBits ( this, col_idx, elem_bits, start,
266             buffer, boff, blen, num_read, remaining );
267     }
ReadBitsVCursor268     inline rc_t ReadBits ( const VCursor *self, int64_t row_id, uint32_t col_idx,
269         uint32_t elem_bits, uint32_t start, void *buffer, uint32_t boff,
270         uint32_t blen, uint32_t *num_read, uint32_t *remaining ) const throw()
271     {
272         return VCursorReadBitsDirect ( this, row_id, col_idx, elem_bits,
273             start, buffer, boff, blen, num_read, remaining );
274     }
275 
276 
277     /* CellData
278      *  access pointer to single cell of potentially bit-aligned column data
279      *  can fail if row is dynamically generated
280      *
281      *  "col_idx" [ IN ] - index of column to be read, returned by "AddColumn"
282      *
283      *  "elem_bits" [ OUT, NULL OKAY ] - optional return parameter for
284      *  element size in bits
285      *
286      *  "base" [ OUT ] and "boff" [ OUT, NULL OKAY ] -
287      *  compound return parameter for pointer to row starting bit
288      *  where "boff" is in BITS
289      *
290      *  "row_len" [ OUT, NULL OKAY ] - the number of elements in cell
291      */
CellDataVCursor292     inline rc_t CellData ( uint32_t col_idx, uint32_t *elem_bits,
293         const void **base, uint32_t *boff, uint32_t *row_len ) const throw()
294     {
295         return VCursorCellData ( this, col_idx, elem_bits, base, boff, row_len );
296     }
CellDataVCursor297     inline rc_t CellData ( int64_t row_id, uint32_t col_idx, uint32_t *elem_bits,
298         const void **base, uint32_t *boff, uint32_t *row_len ) const throw()
299     {
300         return VCursorCellDataDirect ( this, row_id, col_idx, elem_bits,
301             base, boff, row_len );
302     }
303 
304     /* Default
305      *  give a default row value for column
306      *
307      *  "col_idx" [ IN ] - index of column to be read, returned by "AddColumn"
308      *
309      *  "elem_bits" [ IN ] - stated element size in bits, required
310      *  to be compatible with the actual element size
311      *
312      *  "buffer" [ IN ] and "boff" [ IN ] - compound pointer and offset
313      *  to start of default row data where "boff" is in BITS
314      *
315      *  "row_len" [ IN ] - the number of elements in default row
316      */
DefaultVCursor317     inline rc_t Default ( uint32_t col_idx, uint32_t elem_bits,
318         const void *buffer, uint32_t boff, uint32_t row_len ) throw()
319     {
320         return VCursorDefault ( this, col_idx, elem_bits, buffer, boff, row_len );
321     }
322 
323 
324     /* Write
325      *  append bit-aligned column data to row
326      *
327      *  "col_idx" [ IN ] - index of column to be read, returned by "AddColumn"
328      *
329      *  "elem_bits" [ IN ] - stated element size in bits, required
330      *  to be compatible with the actual element size
331      *
332      *  "buffer" [ IN ] and "boff" [ IN ] - compound pointer and offset
333      *  to start of default row data where "boff" is in BITS
334      *
335      *  "count" [ IN ] - the number of elements to append
336      */
WriteVCursor337     inline rc_t Write ( uint32_t col_idx, uint32_t elem_bits,
338         const void *buffer, uint32_t boff, uint32_t count ) throw()
339     {
340         return VCursorWrite ( this, col_idx, elem_bits, buffer, boff, count );
341     }
342 
343 
344     /* Commit
345      *  commit changes made to cursor
346      *  fails if row is open
347      */
CommitVCursor348     inline rc_t Commit () throw()
349     { return VCursorCommit ( this ); }
350 
351 
352     /* OpenParent
353      *  duplicate reference to parent table
354      *  NB - returned reference must be released
355      */
OpenParentVCursor356     inline rc_t OpenParent ( const VTable **tbl ) const throw()
357     { return VCursorOpenParentRead ( this, tbl ); }
358 
OpenParentVCursor359     inline rc_t OpenParent ( VTable **tbl ) throw()
360     { return VCursorOpenParentUpdate ( this, tbl ); }
361 
362 
363     /* GetUserData
364      * SetUserData
365      *  store/retrieve an opaque pointer to user data
366      *
367      *  "data" [ OUT ] - return parameter for getting data
368      *  "data" [ IN ] - parameter for setting data
369      *
370      *  "destroy" [ IN, NULL OKAY ] - optional destructor param
371      *  invoked from destructor of "self"
372      */
GetUserDataVCursor373     inline rc_t GetUserData ( void **data ) const throw()
374     { return VCursorGetUserData ( this, data ); }
375 
SetUserDataVCursor376     inline rc_t SetUserData ( void *data,
377         void ( CC * destroy ) ( void *data ) = 0 ) const throw()
378     { return VCursorSetUserData ( this, data, destroy ); }
379 
380 
381 private:
382     VCursor ();
383     ~ VCursor ();
384     VCursor ( const VCursor& );
385     VCursor &operator = ( const VCursor& );
386 };
387 
388 #endif // _hpp_vdb_cursor_
389