]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/nextid.c
Clean up
[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         if( bdb->bi_lastid > id ) id = bdb_lastid;
90
91         id++;
92         data.size = sizeof( id );
93
94         /* put new value */
95         rc = bdb->bi_nextid->bdi_db->put( bdb->bi_nextid->bdi_db,
96                 ltid, &key, &data, 0 );
97
98         switch(rc) {
99         case DB_LOCK_DEADLOCK:
100         case DB_LOCK_NOTGRANTED:
101                 goto retry;
102
103         case 0:
104                 *out = id;
105
106                 bdb->bi_lastid = id;
107
108                 rc = txn_commit( ltid, 0 );
109
110                 if( rc != 0 ) {
111                         Debug( LDAP_DEBUG_ANY,
112                                 "=> bdb_next_id: commit failed: %s (%d)\n",
113                                 db_strerror(rc), rc, 0 );
114                 }
115                 break;
116
117         default:
118                 Debug( LDAP_DEBUG_ANY,
119                         "=> bdb_next_id: put failed: %s (%d)\n",
120                         db_strerror(rc), rc, 0 );
121 done:   (void) txn_abort( ltid );
122         }
123
124         return rc;
125 }
126
127 int bdb_last_id( BackendDB *be, DB_TXN *tid )
128 {
129         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
130         int rc;
131         ID kid = NOID;
132         ID id;
133         DBT key, data;
134
135         DBTzero( &key );
136         key.data = (char *) &kid;
137         key.size = sizeof( kid );
138
139         DBTzero( &data );
140         data.data = (char *) &id;
141         data.ulen = sizeof( id );
142         data.flags = DB_DBT_USERMEM;
143
144         /* get existing value for read/modify/write */
145         rc = bdb->bi_nextid->bdi_db->get( bdb->bi_nextid->bdi_db,
146                 tid, &key, &data, 0 );
147
148         switch(rc) {
149         case DB_NOTFOUND:
150                 id = 0;
151                 rc = 0;
152                 break;
153
154         case 0:
155                 if ( data.size != sizeof( id ) ) {
156                         Debug( LDAP_DEBUG_ANY,
157                                 "=> bdb_last_id: get size mismatch: expected %ld, got %ld\n",
158                                 (long) sizeof( id ), (long) data.size, 0 );
159                         rc = -1;
160                         goto done;
161                 }
162                 break;
163
164         default:
165                 Debug( LDAP_DEBUG_ANY,
166                         "=> bdb_next_id: get failed: %s (%d)\n",
167                         db_strerror(rc), rc, 0 );
168                 goto done;
169         }
170
171         bdb->bi_lastid = id;
172
173 done:
174         return rc;
175 }