1 /*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)rec_seq.c 8.2 (Berkeley) 09/07/93";
10 #endif /* not lint */
11
12 #include <sys/types.h>
13
14 #include <errno.h>
15 #include <limits.h>
16 #include <stdio.h>
17 #include <string.h>
18
19 #include <db.h>
20 #include "recno.h"
21
22 /*
23 * __REC_SEQ -- Recno sequential scan interface.
24 *
25 * Parameters:
26 * dbp: pointer to access method
27 * key: key for positioning and return value
28 * data: data return value
29 * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV.
30 *
31 * Returns:
32 * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
33 */
34 int
__rec_seq(dbp,key,data,flags)35 __rec_seq(dbp, key, data, flags)
36 const DB *dbp;
37 DBT *key, *data;
38 u_int flags;
39 {
40 BTREE *t;
41 EPG *e;
42 recno_t nrec;
43 int status;
44
45 t = dbp->internal;
46
47 /* Toss any page pinned across calls. */
48 if (t->bt_pinned != NULL) {
49 mpool_put(t->bt_mp, t->bt_pinned, 0);
50 t->bt_pinned = NULL;
51 }
52
53 switch(flags) {
54 case R_CURSOR:
55 if ((nrec = *(recno_t *)key->data) == 0)
56 goto einval;
57 break;
58 case R_NEXT:
59 if (ISSET(t, B_SEQINIT)) {
60 nrec = t->bt_rcursor + 1;
61 break;
62 }
63 /* FALLTHROUGH */
64 case R_FIRST:
65 nrec = 1;
66 break;
67 case R_PREV:
68 if (ISSET(t, B_SEQINIT)) {
69 if ((nrec = t->bt_rcursor - 1) == 0)
70 return (RET_SPECIAL);
71 break;
72 }
73 /* FALLTHROUGH */
74 case R_LAST:
75 if (!ISSET(t, R_EOF | R_INMEM) &&
76 t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
77 return (RET_ERROR);
78 nrec = t->bt_nrecs;
79 break;
80 default:
81 einval: errno = EINVAL;
82 return (RET_ERROR);
83 }
84
85 if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) {
86 if (!ISSET(t, R_EOF | R_INMEM) &&
87 (status = t->bt_irec(t, nrec)) != RET_SUCCESS)
88 return (status);
89 if (t->bt_nrecs == 0 || nrec > t->bt_nrecs)
90 return (RET_SPECIAL);
91 }
92
93 if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL)
94 return (RET_ERROR);
95
96 SET(t, B_SEQINIT);
97 t->bt_rcursor = nrec;
98
99 status = __rec_ret(t, e, nrec, key, data);
100 if (ISSET(t, B_DB_LOCK))
101 mpool_put(t->bt_mp, e->page, 0);
102 else
103 t->bt_pinned = e->page;
104 return (status);
105 }
106