11573Srgrimes/*- 214287Spst * Copyright (c) 1991, 1993, 1994 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * Redistribution and use in source and binary forms, with or without 61573Srgrimes * modification, are permitted provided that the following conditions 71573Srgrimes * are met: 81573Srgrimes * 1. Redistributions of source code must retain the above copyright 91573Srgrimes * notice, this list of conditions and the following disclaimer. 101573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111573Srgrimes * notice, this list of conditions and the following disclaimer in the 121573Srgrimes * documentation and/or other materials provided with the distribution. 131573Srgrimes * 4. Neither the name of the University nor the names of its contributors 141573Srgrimes * may be used to endorse or promote products derived from this software 151573Srgrimes * without specific prior written permission. 161573Srgrimes * 171573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271573Srgrimes * SUCH DAMAGE. 281573Srgrimes */ 291573Srgrimes 30111010Snectar#include <sys/cdefs.h> 311573Srgrimes#ifndef lint 32111010Snectar/* XXX use __SCCSID */ 33111010Snectarstatic char sccsid[] __unused = "@(#)rec_seq.c 8.3 (Berkeley) 7/14/94"; 341573Srgrimes#endif /* not lint */ 3592986Sobrien__FBSDID("$FreeBSD: releng/10.2/lib/libc/db/recno/rec_seq.c 189327 2009-03-04 00:58:04Z delphij $"); 361573Srgrimes 371573Srgrimes#include <sys/types.h> 381573Srgrimes 391573Srgrimes#include <errno.h> 401573Srgrimes#include <limits.h> 411573Srgrimes#include <stdio.h> 421573Srgrimes#include <string.h> 431573Srgrimes 441573Srgrimes#include <db.h> 451573Srgrimes#include "recno.h" 461573Srgrimes 471573Srgrimes/* 481573Srgrimes * __REC_SEQ -- Recno sequential scan interface. 491573Srgrimes * 501573Srgrimes * Parameters: 511573Srgrimes * dbp: pointer to access method 521573Srgrimes * key: key for positioning and return value 531573Srgrimes * data: data return value 541573Srgrimes * flags: R_CURSOR, R_FIRST, R_LAST, R_NEXT, R_PREV. 551573Srgrimes * 561573Srgrimes * Returns: 571573Srgrimes * RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key. 581573Srgrimes */ 591573Srgrimesint 60189291Sdelphij__rec_seq(const DB *dbp, DBT *key, DBT *data, u_int flags) 611573Srgrimes{ 621573Srgrimes BTREE *t; 631573Srgrimes EPG *e; 641573Srgrimes recno_t nrec; 651573Srgrimes int status; 661573Srgrimes 671573Srgrimes t = dbp->internal; 681573Srgrimes 691573Srgrimes /* Toss any page pinned across calls. */ 701573Srgrimes if (t->bt_pinned != NULL) { 711573Srgrimes mpool_put(t->bt_mp, t->bt_pinned, 0); 721573Srgrimes t->bt_pinned = NULL; 731573Srgrimes } 741573Srgrimes 751573Srgrimes switch(flags) { 761573Srgrimes case R_CURSOR: 771573Srgrimes if ((nrec = *(recno_t *)key->data) == 0) 781573Srgrimes goto einval; 791573Srgrimes break; 801573Srgrimes case R_NEXT: 8114287Spst if (F_ISSET(&t->bt_cursor, CURS_INIT)) { 8214287Spst nrec = t->bt_cursor.rcursor + 1; 831573Srgrimes break; 841573Srgrimes } 851573Srgrimes /* FALLTHROUGH */ 861573Srgrimes case R_FIRST: 871573Srgrimes nrec = 1; 881573Srgrimes break; 891573Srgrimes case R_PREV: 9014287Spst if (F_ISSET(&t->bt_cursor, CURS_INIT)) { 9114287Spst if ((nrec = t->bt_cursor.rcursor - 1) == 0) 921573Srgrimes return (RET_SPECIAL); 931573Srgrimes break; 941573Srgrimes } 951573Srgrimes /* FALLTHROUGH */ 961573Srgrimes case R_LAST: 9714287Spst if (!F_ISSET(t, R_EOF | R_INMEM) && 981573Srgrimes t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR) 991573Srgrimes return (RET_ERROR); 1001573Srgrimes nrec = t->bt_nrecs; 1011573Srgrimes break; 1021573Srgrimes default: 1031573Srgrimeseinval: errno = EINVAL; 1041573Srgrimes return (RET_ERROR); 1051573Srgrimes } 106189327Sdelphij 1071573Srgrimes if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) { 10814287Spst if (!F_ISSET(t, R_EOF | R_INMEM) && 1091573Srgrimes (status = t->bt_irec(t, nrec)) != RET_SUCCESS) 1101573Srgrimes return (status); 1111573Srgrimes if (t->bt_nrecs == 0 || nrec > t->bt_nrecs) 1121573Srgrimes return (RET_SPECIAL); 1131573Srgrimes } 1141573Srgrimes 1151573Srgrimes if ((e = __rec_search(t, nrec - 1, SEARCH)) == NULL) 1161573Srgrimes return (RET_ERROR); 1171573Srgrimes 11814287Spst F_SET(&t->bt_cursor, CURS_INIT); 11914287Spst t->bt_cursor.rcursor = nrec; 1201573Srgrimes 1211573Srgrimes status = __rec_ret(t, e, nrec, key, data); 12214287Spst if (F_ISSET(t, B_DB_LOCK)) 1231573Srgrimes mpool_put(t->bt_mp, e->page, 0); 1241573Srgrimes else 1251573Srgrimes t->bt_pinned = e->page; 1261573Srgrimes return (status); 1271573Srgrimes} 128