]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/nextid.c
Last changes should have been #ifdef
[openldap] / servers / slapd / back-bdb / nextid.c
1 /* init.c - initialize bdb backend */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11 #include <ac/string.h>
12
13 #include "back-bdb.h"
14
15 int bdb_next_id( BackendDB *be, DB_TXN *tid, ID *out )
16 {
17         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
18         int rc;
19         ID kid = NOID;
20         ID id;
21         DBT key, data;
22         DB_TXN  *ltid;
23
24         DBTzero( &key );
25         key.data = (char *) &kid;
26         key.size = sizeof( kid );
27
28         DBTzero( &data );
29         data.data = (char *) &id;
30         data.ulen = sizeof( id );
31         data.flags = DB_DBT_USERMEM;
32
33         if( 0 ) {
34 retry:  if( tid != NULL ) {
35                         /* nested transaction, abort and return */
36                         (void) txn_abort( ltid );
37                         Debug( LDAP_DEBUG_ANY,
38                                 "=> bdb_next_id: aborted!\n",
39                                 0, 0, 0 );
40                         return rc;
41                 }
42                 rc = txn_abort( ltid );
43                 if( rc != 0 ) {
44                         Debug( LDAP_DEBUG_ANY,
45                                 "=> bdb_next_id: txn_abort failed: %s (%d)\n",
46                                 db_strerror(rc), rc, 0 );
47                         return rc;
48                 }
49         }
50
51         rc = txn_begin( bdb->bi_dbenv, tid, &ltid, 0 );
52         if( rc != 0 ) {
53                 Debug( LDAP_DEBUG_ANY,
54                         "=> bdb_next_id: txn_begin failed: %s (%d)\n",
55                         db_strerror(rc), rc, 0 );
56                 return rc;
57         }
58
59         /* get existing value for read/modify/write */
60         rc = bdb->bi_nextid->bdi_db->get( bdb->bi_nextid->bdi_db,
61                 ltid, &key, &data, DB_RMW );
62
63         switch(rc) {
64         case DB_LOCK_DEADLOCK:
65         case DB_LOCK_NOTGRANTED:
66                 goto retry;
67
68         case DB_NOTFOUND:
69                 id = 0;
70                 break;
71
72         case 0:
73                 if ( data.size != sizeof( id ) ) {
74                         Debug( LDAP_DEBUG_ANY,
75                                 "=> bdb_next_id: get size mismatch: expected %ld, got %ld\n",
76                                 (long) sizeof( id ), (long) data.size, 0 );
77                         rc = -1;
78                         goto done;
79                 }
80                 break;
81
82         default:
83                 Debug( LDAP_DEBUG_ANY,
84                         "=> bdb_next_id: get failed: %s (%d)\n",
85                         db_strerror(rc), rc, 0 );
86                 goto done;
87         }
88
89         id++;
90         data.size = sizeof( id );
91
92         /* put new value */
93         rc = bdb->bi_nextid->bdi_db->put( bdb->bi_nextid->bdi_db,
94                 ltid, &key, &data, 0 );
95
96         switch(rc) {
97         case DB_LOCK_DEADLOCK:
98         case DB_LOCK_NOTGRANTED:
99                 goto retry;
100
101         case 0:
102                 *out = id;
103
104                 bdb->bi_lastid = id;
105
106                 rc = txn_commit( ltid, 0 );
107
108                 if( rc != 0 ) {
109                         Debug( LDAP_DEBUG_ANY,
110                                 "=> bdb_next_id: commit failed: %s (%d)\n",
111                                 db_strerror(rc), rc, 0 );
112                 }
113                 break;
114
115         default:
116                 Debug( LDAP_DEBUG_ANY,
117                         "=> bdb_next_id: put failed: %s (%d)\n",
118                         db_strerror(rc), rc, 0 );
119 done:   (void) txn_abort( ltid );
120         }
121
122         return rc;
123 }
124
125 int bdb_last_id( BackendDB *be, DB_TXN *tid )
126 {
127         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
128         int rc;
129         ID kid = NOID;
130         ID id;
131         DBT key, data;
132
133         DBTzero( &key );
134         key.data = (char *) &kid;
135         key.size = sizeof( kid );
136
137         DBTzero( &data );
138         data.data = (char *) &id;
139         data.ulen = sizeof( id );
140         data.flags = DB_DBT_USERMEM;
141
142 retry:
143         /* get existing value for read/modify/write */
144         rc = bdb->bi_nextid->bdi_db->get( bdb->bi_nextid->bdi_db,
145                 tid, &key, &data, 0 );
146
147         switch(rc) {
148         case DB_LOCK_DEADLOCK:
149         case DB_LOCK_NOTGRANTED:
150                 goto retry;
151
152         case DB_NOTFOUND:
153                 id = 0;
154                 rc = 0;
155                 break;
156
157         case 0:
158                 if ( data.size != sizeof( id ) ) {
159                         Debug( LDAP_DEBUG_ANY,
160                                 "=> bdb_last_id: get size mismatch: expected %ld, got %ld\n",
161                                 (long) sizeof( id ), (long) data.size, 0 );
162                         rc = -1;
163                         goto done;
164                 }
165                 break;
166
167         default:
168                 Debug( LDAP_DEBUG_ANY,
169                         "=> bdb_next_id: get failed: %s (%d)\n",
170                         db_strerror(rc), rc, 0 );
171                 goto done;
172         }
173
174         bdb->bi_lastid = id;
175
176 done:
177         return rc;
178 }