tt/mini_isam: remove all ancient sccsid blocks
[oweals/cde.git] / cde / lib / tt / mini_isam / ischange1key.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: ischange1key.c /main/3 1995/10/23 11:36:41 rswiston $                                                        */
28 /*
29  * Copyright (c) 1988 by Sun Microsystems, Inc.
30  */
31
32 /*
33  * ischange1key.c
34  *
35  * Description: 
36  *      Update an index if necessary.
37  *      
38  *
39  */
40
41 #include "isam_impl.h"
42
43 extern long *ismaxlong;
44
45 int
46 _change1key(Fcb *fcb, Keydesc2 *pkeydesc2, char *record,
47             char *oldrecord, Recno recnum, char *newkey)
48 {
49     char                keybuf1[MAXKEYSIZE];
50     char                keybuf2[MAXKEYSIZE];
51     Btree               *btree;
52     char                *pkey;
53
54     /*
55      * Special case when there is no primary key.
56      */
57     if (pkeydesc2->k2_nparts == 0)
58         return (ISOK);
59
60     /* Get old key value. */
61     memset((char *)keybuf1, 0, pkeydesc2->k2_len);
62     _iskey_extract(pkeydesc2, oldrecord, keybuf1);
63     strecno(recnum, keybuf1);
64     
65     /* Get new key value. */
66     memset((char *)keybuf2, 0, pkeydesc2->k2_len);
67     _iskey_extract(pkeydesc2, record, keybuf2);
68     strecno(recnum, keybuf2);
69
70   
71     /*
72      * See if the key changed.
73      */
74     if (memcmp(keybuf1, keybuf2, pkeydesc2->k2_len)) {
75         
76         /*
77          * Delete the old key entry from B tree.
78          */
79         btree = _isbtree_create(fcb, pkeydesc2);
80         _isbtree_search(btree, keybuf1);
81
82         if (ALLOWS_DUPS2(pkeydesc2)) {
83             
84             /*
85              * We must now scan all the duplicates till we found one with
86              * matching recno. We are positioned just before the first duplicate.
87              * Remember that the duplicates are ordered by their serial number.
88              *
89              * If too many duplicate entries exists, the performance will be
90              * poor.
91              */
92             while ((pkey = _isbtree_next(btree)) != NULL) {
93                 if (ldrecno(pkey + KEY_RECNO_OFF) == recnum)
94                     break;                           /* We found the entry */
95             }
96             
97             if (pkey == NULL) 
98                 _isfatal_error("_del1key() cannot find entry in B tree");
99             
100             _isbtree_remove(btree);
101         }
102         else {
103             
104             if ((pkey = _isbtree_current(btree)) == NULL ||
105                 ldrecno(pkey + KEY_RECNO_OFF) != recnum)
106                 _isfatal_error("_del1key() cannot find entry in B tree");
107             
108             _isbtree_remove(btree);
109         }
110         _isbtree_destroy(btree);
111
112         /*
113          * Insert new key entry into B tree.
114          */
115         
116         btree = _isbtree_create(fcb, pkeydesc2);
117         
118         if (ALLOWS_DUPS2(pkeydesc2)) {
119             
120             /* 
121              * Duplicates allowed on this key. 
122              * Try to read the last duplicate (with the highest serial number).
123              * If such duplicate exists, the inserted key entry will be
124              * assigned next higher value for duplicate serial number.
125              * If there is no such duplicate, assign duplicate serial number 1.
126              */
127             strecno(recnum, keybuf2 + KEY_RECNO_OFF);
128             memcpy( keybuf2 + KEY_DUPS_OFF,(char *)ismaxlong, LONGSIZE);
129             _isbtree_search(btree, keybuf2);
130             
131             if ((pkey = _isbtree_current(btree)) != NULL &&
132                 memcmp(pkey + RECNOSIZE + DUPIDSIZE, 
133                        keybuf2 + RECNOSIZE + DUPIDSIZE,
134                        pkeydesc2->k2_len - RECNOSIZE - DUPIDSIZE) == 0) {
135                 
136                 /*
137                  * A duplicate exists. Assign +1 value for the new serial
138                  * number.
139                  */
140                 stlong(ldlong(pkey + KEY_DUPS_OFF) + 1, keybuf2 + KEY_DUPS_OFF);
141
142                 /*
143                  * Indicate that there are allowed duplicate key values.
144                  */
145                 isdupl = 1;
146             }
147             else {
148                 
149                 /*
150                  * This is the first duplicate. Assign serial number 1.
151                  */
152                 stlong(1L, keybuf2 + KEY_DUPS_OFF);
153             }
154             
155             _isbtree_insert(btree, keybuf2);
156             _isbtree_destroy(btree);
157         }
158
159         
160         
161         else {
162             
163             /* Duplicates not allowed on this key.
164              * Set TID part to maximum value, causing the search path 
165              * to point just past the possible duplicate in the key file 
166              * If there is no duplicate, this is the correct spot to 
167              * insert the new key entry.                              
168              */
169             
170             memcpy( keybuf2 + KEY_RECNO_OFF,(char *)ismaxlong, LONGSIZE);
171             _isbtree_search (btree, keybuf2);
172             
173             if ((pkey = _isbtree_current(btree)) != NULL &&
174                 memcmp(pkey + RECNOSIZE, keybuf2 + RECNOSIZE,
175                        pkeydesc2->k2_len - RECNOSIZE) == 0) {
176                 _isbtree_destroy(btree);
177                 return (EDUPL);
178             }
179             
180             strecno(recnum, keybuf2 + KEY_RECNO_OFF);
181             _isbtree_insert(btree, keybuf2);
182             _isbtree_destroy(btree);
183         }
184     }
185
186     /*
187      * Return new key position.
188      */
189     if (newkey != NULL)
190         memcpy( newkey,keybuf2, pkeydesc2->k2_len);
191         
192     return (ISOK);
193 }
194