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 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