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