d69ce7d36d7b52d81d2ba0e87de21a6b493d54f6
[oweals/cde.git] / cde / lib / tt / mini_isam / isadd1key.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*%%  (c) Copyright 1993, 1994 Hewlett-Packard Company                   */
24 /*%%  (c) Copyright 1993, 1994 International Business Machines Corp.     */
25 /*%%  (c) Copyright 1993, 1994 Sun Microsystems, Inc.                    */
26 /*%%  (c) Copyright 1993, 1994 Novell, Inc.                              */
27 /*%%  $XConsortium: isadd1key.c /main/3 1995/10/23 11:33:17 rswiston $                                                   */
28 #ifndef lint
29     static char sccsid[] = "@(#)isadd1key.c 1.3 89/07/17 Copyr 1988 Sun Micro";
30 #endif
31 /*
32  * Copyright (c) 1988 by Sun Microsystems, Inc.
33  */
34
35 /*
36  * isadd1key.c
37  *
38  * Description: 
39  *      Add an entry to B tree.
40  *      
41  *
42  */
43
44 #include "isam_impl.h"
45
46 extern long *ismaxlong;
47
48 int
49 _add1key(Fcb *fcb, Keydesc2 *pkeydesc2, char *record, Recno recnum, char *newkey)
50 {
51     char                keybuf[MAXKEYSIZE];
52     Btree               *btree;
53     char                *pkey;
54     
55     /*
56      * Special case when there is no primary key.
57      */
58     if (pkeydesc2->k2_nparts == 0)
59         return (ISOK);
60     
61     memset((char *)keybuf, 0, pkeydesc2->k2_len);
62     _iskey_extract(pkeydesc2, record, keybuf);
63     
64     btree = _isbtree_create(fcb, pkeydesc2);
65     
66     if (ALLOWS_DUPS2(pkeydesc2)) {
67         
68         /* 
69          * Duplicates allowed on this key. 
70          * Try to read the last duplicate (with the highest serial number).
71          * If such duplicate exists, the inserted key entry will be
72          * assigned next higher value for duplicate serial number.
73          * If there is no such duplicate, assign duplicate serial number 1.
74          */
75         strecno(recnum, keybuf + KEY_RECNO_OFF);
76         memcpy(keybuf + KEY_DUPS_OFF, (char *)ismaxlong, LONGSIZE);
77         _isbtree_search(btree, keybuf);
78         
79         if ((pkey = _isbtree_current(btree)) != NULL &&
80             memcmp(pkey + RECNOSIZE + DUPIDSIZE, 
81                    keybuf + RECNOSIZE + DUPIDSIZE,
82                    pkeydesc2->k2_len - RECNOSIZE - DUPIDSIZE) == 0) {
83             
84             /*
85              * A duplicate exists. Assign +1 value for the new serial
86              * number.
87              */
88             stlong(ldlong(pkey + KEY_DUPS_OFF) + 1, keybuf + KEY_DUPS_OFF);
89
90             /*
91              * Set isdupl to 1 to indicate allowed duplicates exist.
92              */
93             isdupl = 1;
94         }
95         else {
96             
97             /*
98              * This is the first duplicate. Assign serial number 1.
99              */
100             stlong(1L, keybuf + KEY_DUPS_OFF);
101         }
102         
103         _isbtree_insert(btree, keybuf);
104         _isbtree_destroy(btree);
105     }
106     else {
107         
108         /* Duplicates not allowed on this key.
109          * Set TID part to maximum value, causing the search path 
110          * to point just past the possible duplicate in the key file 
111          * If there is no duplicate, this is the correct spot to 
112          * insert the new key entry.                              
113          */
114         
115         memcpy( keybuf + KEY_RECNO_OFF,(char *)ismaxlong, LONGSIZE);
116         _isbtree_search (btree, keybuf);
117         
118         if ((pkey = _isbtree_current(btree)) != NULL &&
119             memcmp(pkey + RECNOSIZE, keybuf + RECNOSIZE,
120                    pkeydesc2->k2_len - RECNOSIZE) == 0) {
121             _isbtree_destroy(btree);
122             return (EDUPL);
123         }
124         
125         strecno(recnum, keybuf + KEY_RECNO_OFF);
126         _isbtree_insert(btree, keybuf);
127         _isbtree_destroy(btree);
128     }
129
130     /*
131      * Return new key position.
132      */
133     if (newkey != NULL)
134         memcpy( newkey,keybuf, pkeydesc2->k2_len);
135
136     return (ISOK);
137 }