2011-12-02 20:40:33 +04:00
/*
r22775: For the cluster code I've developed a wrapper around tdb to put different
database backends in place dynamically.
The main abstractions are db_context and db_record, it should be mainly
self-describing, see include/dbwrap.h. You open the db just as you would open
a tdb, this time with db_open(). If you want to fetch a record, just do the
db->fetch() call, if you want to do operations on it, you need to get it with
fetch_locked().
I added dbwrap_file.c (not heavily tested lately) as an example for what can
be done with that abstraction, uses a file per key. So if anybody is willing
to shape that up, we might have a chance on reiserfs again.... :-)
This abstraction works fine for brlock.tdb, locking.tdb, connections.tdb and
sessionid.tdb. It should work fine for the others as well, I just did not yet
get around to convert them.
If nobody loudly screams NO, then I will import the code that uses this soon.
Volker
(This used to be commit e9d7484ca246cfca4a1fd23be35edc2783136ebe)
2007-05-10 14:42:13 +04:00
Unix SMB / CIFS implementation .
Database interface wrapper
Copyright ( C ) Jim McDonough < jmcd @ us . ibm . com > 2006
Major code contributions from Aleksey Fedoseev ( fedoseev @ ru . ibm . com )
2011-12-02 20:40:33 +04:00
r22775: For the cluster code I've developed a wrapper around tdb to put different
database backends in place dynamically.
The main abstractions are db_context and db_record, it should be mainly
self-describing, see include/dbwrap.h. You open the db just as you would open
a tdb, this time with db_open(). If you want to fetch a record, just do the
db->fetch() call, if you want to do operations on it, you need to get it with
fetch_locked().
I added dbwrap_file.c (not heavily tested lately) as an example for what can
be done with that abstraction, uses a file per key. So if anybody is willing
to shape that up, we might have a chance on reiserfs again.... :-)
This abstraction works fine for brlock.tdb, locking.tdb, connections.tdb and
sessionid.tdb. It should work fine for the others as well, I just did not yet
get around to convert them.
If nobody loudly screams NO, then I will import the code that uses this soon.
Volker
(This used to be commit e9d7484ca246cfca4a1fd23be35edc2783136ebe)
2007-05-10 14:42:13 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
r22775: For the cluster code I've developed a wrapper around tdb to put different
database backends in place dynamically.
The main abstractions are db_context and db_record, it should be mainly
self-describing, see include/dbwrap.h. You open the db just as you would open
a tdb, this time with db_open(). If you want to fetch a record, just do the
db->fetch() call, if you want to do operations on it, you need to get it with
fetch_locked().
I added dbwrap_file.c (not heavily tested lately) as an example for what can
be done with that abstraction, uses a file per key. So if anybody is willing
to shape that up, we might have a chance on reiserfs again.... :-)
This abstraction works fine for brlock.tdb, locking.tdb, connections.tdb and
sessionid.tdb. It should work fine for the others as well, I just did not yet
get around to convert them.
If nobody loudly screams NO, then I will import the code that uses this soon.
Volker
(This used to be commit e9d7484ca246cfca4a1fd23be35edc2783136ebe)
2007-05-10 14:42:13 +04:00
( at your option ) any later version .
2011-12-02 20:40:33 +04:00
r22775: For the cluster code I've developed a wrapper around tdb to put different
database backends in place dynamically.
The main abstractions are db_context and db_record, it should be mainly
self-describing, see include/dbwrap.h. You open the db just as you would open
a tdb, this time with db_open(). If you want to fetch a record, just do the
db->fetch() call, if you want to do operations on it, you need to get it with
fetch_locked().
I added dbwrap_file.c (not heavily tested lately) as an example for what can
be done with that abstraction, uses a file per key. So if anybody is willing
to shape that up, we might have a chance on reiserfs again.... :-)
This abstraction works fine for brlock.tdb, locking.tdb, connections.tdb and
sessionid.tdb. It should work fine for the others as well, I just did not yet
get around to convert them.
If nobody loudly screams NO, then I will import the code that uses this soon.
Volker
(This used to be commit e9d7484ca246cfca4a1fd23be35edc2783136ebe)
2007-05-10 14:42:13 +04:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2011-12-02 20:40:33 +04:00
r22775: For the cluster code I've developed a wrapper around tdb to put different
database backends in place dynamically.
The main abstractions are db_context and db_record, it should be mainly
self-describing, see include/dbwrap.h. You open the db just as you would open
a tdb, this time with db_open(). If you want to fetch a record, just do the
db->fetch() call, if you want to do operations on it, you need to get it with
fetch_locked().
I added dbwrap_file.c (not heavily tested lately) as an example for what can
be done with that abstraction, uses a file per key. So if anybody is willing
to shape that up, we might have a chance on reiserfs again.... :-)
This abstraction works fine for brlock.tdb, locking.tdb, connections.tdb and
sessionid.tdb. It should work fine for the others as well, I just did not yet
get around to convert them.
If nobody loudly screams NO, then I will import the code that uses this soon.
Volker
(This used to be commit e9d7484ca246cfca4a1fd23be35edc2783136ebe)
2007-05-10 14:42:13 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
r22775: For the cluster code I've developed a wrapper around tdb to put different
database backends in place dynamically.
The main abstractions are db_context and db_record, it should be mainly
self-describing, see include/dbwrap.h. You open the db just as you would open
a tdb, this time with db_open(). If you want to fetch a record, just do the
db->fetch() call, if you want to do operations on it, you need to get it with
fetch_locked().
I added dbwrap_file.c (not heavily tested lately) as an example for what can
be done with that abstraction, uses a file per key. So if anybody is willing
to shape that up, we might have a chance on reiserfs again.... :-)
This abstraction works fine for brlock.tdb, locking.tdb, connections.tdb and
sessionid.tdb. It should work fine for the others as well, I just did not yet
get around to convert them.
If nobody loudly screams NO, then I will import the code that uses this soon.
Volker
(This used to be commit e9d7484ca246cfca4a1fd23be35edc2783136ebe)
2007-05-10 14:42:13 +04:00
*/
# include "includes.h"
2011-07-07 19:42:08 +04:00
# include "dbwrap/dbwrap.h"
2011-07-06 18:40:21 +04:00
# include "dbwrap/dbwrap_private.h"
2011-08-17 10:35:21 +04:00
# include "util_tdb.h"
2011-07-06 18:40:21 +04:00
r22775: For the cluster code I've developed a wrapper around tdb to put different
database backends in place dynamically.
The main abstractions are db_context and db_record, it should be mainly
self-describing, see include/dbwrap.h. You open the db just as you would open
a tdb, this time with db_open(). If you want to fetch a record, just do the
db->fetch() call, if you want to do operations on it, you need to get it with
fetch_locked().
I added dbwrap_file.c (not heavily tested lately) as an example for what can
be done with that abstraction, uses a file per key. So if anybody is willing
to shape that up, we might have a chance on reiserfs again.... :-)
This abstraction works fine for brlock.tdb, locking.tdb, connections.tdb and
sessionid.tdb. It should work fine for the others as well, I just did not yet
get around to convert them.
If nobody loudly screams NO, then I will import the code that uses this soon.
Volker
(This used to be commit e9d7484ca246cfca4a1fd23be35edc2783136ebe)
2007-05-10 14:42:13 +04:00
/*
* Fall back using fetch_locked if no genuine fetch operation is provided
*/
2011-12-08 16:56:07 +04:00
static NTSTATUS dbwrap_fallback_fetch ( struct db_context * db ,
TALLOC_CTX * mem_ctx ,
TDB_DATA key , TDB_DATA * data )
r22775: For the cluster code I've developed a wrapper around tdb to put different
database backends in place dynamically.
The main abstractions are db_context and db_record, it should be mainly
self-describing, see include/dbwrap.h. You open the db just as you would open
a tdb, this time with db_open(). If you want to fetch a record, just do the
db->fetch() call, if you want to do operations on it, you need to get it with
fetch_locked().
I added dbwrap_file.c (not heavily tested lately) as an example for what can
be done with that abstraction, uses a file per key. So if anybody is willing
to shape that up, we might have a chance on reiserfs again.... :-)
This abstraction works fine for brlock.tdb, locking.tdb, connections.tdb and
sessionid.tdb. It should work fine for the others as well, I just did not yet
get around to convert them.
If nobody loudly screams NO, then I will import the code that uses this soon.
Volker
(This used to be commit e9d7484ca246cfca4a1fd23be35edc2783136ebe)
2007-05-10 14:42:13 +04:00
{
struct db_record * rec ;
2011-12-08 16:51:19 +04:00
rec = dbwrap_fetch_locked ( db , mem_ctx , key ) ;
2011-11-11 03:49:11 +04:00
if ( rec = = NULL ) {
return NT_STATUS_UNSUCCESSFUL ;
r22775: For the cluster code I've developed a wrapper around tdb to put different
database backends in place dynamically.
The main abstractions are db_context and db_record, it should be mainly
self-describing, see include/dbwrap.h. You open the db just as you would open
a tdb, this time with db_open(). If you want to fetch a record, just do the
db->fetch() call, if you want to do operations on it, you need to get it with
fetch_locked().
I added dbwrap_file.c (not heavily tested lately) as an example for what can
be done with that abstraction, uses a file per key. So if anybody is willing
to shape that up, we might have a chance on reiserfs again.... :-)
This abstraction works fine for brlock.tdb, locking.tdb, connections.tdb and
sessionid.tdb. It should work fine for the others as well, I just did not yet
get around to convert them.
If nobody loudly screams NO, then I will import the code that uses this soon.
Volker
(This used to be commit e9d7484ca246cfca4a1fd23be35edc2783136ebe)
2007-05-10 14:42:13 +04:00
}
data - > dsize = rec - > value . dsize ;
data - > dptr = talloc_move ( mem_ctx , & rec - > value . dptr ) ;
TALLOC_FREE ( rec ) ;
2011-11-11 03:49:11 +04:00
return NT_STATUS_OK ;
r22775: For the cluster code I've developed a wrapper around tdb to put different
database backends in place dynamically.
The main abstractions are db_context and db_record, it should be mainly
self-describing, see include/dbwrap.h. You open the db just as you would open
a tdb, this time with db_open(). If you want to fetch a record, just do the
db->fetch() call, if you want to do operations on it, you need to get it with
fetch_locked().
I added dbwrap_file.c (not heavily tested lately) as an example for what can
be done with that abstraction, uses a file per key. So if anybody is willing
to shape that up, we might have a chance on reiserfs again.... :-)
This abstraction works fine for brlock.tdb, locking.tdb, connections.tdb and
sessionid.tdb. It should work fine for the others as well, I just did not yet
get around to convert them.
If nobody loudly screams NO, then I will import the code that uses this soon.
Volker
(This used to be commit e9d7484ca246cfca4a1fd23be35edc2783136ebe)
2007-05-10 14:42:13 +04:00
}
2011-07-04 12:15:44 +04:00
/*
* Fall back using fetch if no genuine exists operation is provided
*/
static int dbwrap_fallback_exists ( struct db_context * db , TDB_DATA key )
{
2011-07-05 15:43:59 +04:00
int res = dbwrap_parse_record ( db , key , NULL , NULL ) ;
return ( res = = - 1 ) ? 0 : 1 ;
2011-07-04 12:15:44 +04:00
}
2009-02-22 02:18:05 +03:00
/*
* Fall back using fetch if no genuine parse operation is provided
*/
2011-12-08 16:58:19 +04:00
static int dbwrap_fallback_parse_record ( struct db_context * db , TDB_DATA key ,
int ( * parser ) ( TDB_DATA key ,
TDB_DATA data ,
void * private_data ) ,
void * private_data )
2009-02-22 02:18:05 +03:00
{
TDB_DATA data ;
int res ;
2011-11-11 03:49:11 +04:00
NTSTATUS status ;
2009-02-22 02:18:05 +03:00
2011-12-08 16:51:19 +04:00
status = dbwrap_fetch ( db , talloc_tos ( ) , key , & data ) ;
2011-11-11 03:49:11 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 15:41:12 +04:00
return - 1 ;
2009-02-22 02:18:05 +03:00
}
res = parser ( key , data , private_data ) ;
TALLOC_FREE ( data . dptr ) ;
return res ;
}
2011-08-17 10:35:21 +04:00
2011-08-16 16:39:19 +04:00
static int delete_record ( struct db_record * rec , void * data )
{
2011-12-08 16:51:19 +04:00
NTSTATUS status = dbwrap_record_delete ( rec ) ;
2011-08-16 16:39:19 +04:00
return NT_STATUS_IS_OK ( status ) ? 0 : - 1 ;
}
/*
* Fallback wipe ipmlementation using traverse and delete if no genuine
* wipe operation is provided
*/
2011-12-08 17:01:27 +04:00
static int dbwrap_fallback_wipe ( struct db_context * db )
2011-08-16 16:39:19 +04:00
{
2011-12-08 17:02:27 +04:00
NTSTATUS status = dbwrap_trans_traverse ( db , delete_record , NULL ) ;
2011-08-16 16:39:19 +04:00
return NT_STATUS_IS_OK ( status ) ? 0 : - 1 ;
}
2011-08-17 16:42:50 +04:00
/*
* Wrapper functions for the backend methods
*/
2011-08-19 12:50:20 +04:00
TDB_DATA dbwrap_record_get_key ( const struct db_record * rec )
{
return rec - > key ;
}
TDB_DATA dbwrap_record_get_value ( const struct db_record * rec )
{
return rec - > value ;
}
2011-08-19 12:51:27 +04:00
NTSTATUS dbwrap_record_store ( struct db_record * rec , TDB_DATA data , int flags )
{
return rec - > store ( rec , data , flags ) ;
}
2011-08-19 12:52:57 +04:00
NTSTATUS dbwrap_record_delete ( struct db_record * rec )
{
return rec - > delete_rec ( rec ) ;
}
2011-08-19 12:53:29 +04:00
struct db_record * dbwrap_fetch_locked ( struct db_context * db ,
TALLOC_CTX * mem_ctx ,
TDB_DATA key )
{
return db - > fetch_locked ( db , mem_ctx , key ) ;
}
2011-08-24 15:08:13 +04:00
NTSTATUS dbwrap_fetch ( struct db_context * db , TALLOC_CTX * mem_ctx ,
TDB_DATA key , TDB_DATA * value )
2011-08-17 10:35:21 +04:00
{
2011-08-24 15:08:13 +04:00
if ( value = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2011-12-08 16:56:07 +04:00
if ( db - > fetch = = NULL ) {
return dbwrap_fallback_fetch ( db , mem_ctx , key , value ) ;
}
2011-11-11 03:49:11 +04:00
return db - > fetch ( db , mem_ctx , key , value ) ;
2011-08-17 10:35:21 +04:00
}
2011-08-17 10:36:52 +04:00
2011-07-04 12:15:44 +04:00
bool dbwrap_exists ( struct db_context * db , TDB_DATA key )
{
int result ;
if ( db - > exists ! = NULL ) {
result = db - > exists ( db , key ) ;
} else {
result = dbwrap_fallback_exists ( db , key ) ;
}
return ( result = = 1 ) ;
}
2011-08-17 10:38:39 +04:00
NTSTATUS dbwrap_store ( struct db_context * db , TDB_DATA key ,
TDB_DATA data , int flags )
{
struct db_record * rec ;
NTSTATUS status ;
2011-12-08 16:51:19 +04:00
rec = dbwrap_fetch_locked ( db , talloc_tos ( ) , key ) ;
2011-08-17 10:38:39 +04:00
if ( rec = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2011-12-08 16:51:19 +04:00
status = dbwrap_record_store ( rec , data , flags ) ;
2011-08-17 10:38:39 +04:00
TALLOC_FREE ( rec ) ;
return status ;
}
2011-08-17 10:36:52 +04:00
NTSTATUS dbwrap_delete ( struct db_context * db , TDB_DATA key )
{
struct db_record * rec ;
NTSTATUS status ;
2011-12-08 16:51:19 +04:00
rec = dbwrap_fetch_locked ( db , talloc_tos ( ) , key ) ;
2011-08-17 10:36:52 +04:00
if ( rec = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2011-12-08 16:51:19 +04:00
status = dbwrap_record_delete ( rec ) ;
2011-08-17 10:36:52 +04:00
TALLOC_FREE ( rec ) ;
return status ;
}
2011-08-17 10:40:53 +04:00
NTSTATUS dbwrap_traverse ( struct db_context * db ,
int ( * f ) ( struct db_record * , void * ) ,
2011-08-17 11:51:12 +04:00
void * private_data ,
int * count )
2011-08-17 10:40:53 +04:00
{
int ret = db - > traverse ( db , f , private_data ) ;
2011-08-17 11:51:12 +04:00
if ( ret < 0 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( count ! = NULL ) {
* count = ret ;
}
return NT_STATUS_OK ;
2011-08-17 10:40:53 +04:00
}
2011-08-17 11:59:25 +04:00
NTSTATUS dbwrap_traverse_read ( struct db_context * db ,
int ( * f ) ( struct db_record * , void * ) ,
void * private_data ,
int * count )
{
int ret = db - > traverse_read ( db , f , private_data ) ;
if ( ret < 0 ) {
return NT_STATUS_INTERNAL_DB_CORRUPTION ;
}
if ( count ! = NULL ) {
* count = ret ;
}
return NT_STATUS_OK ;
}
2011-07-05 15:10:30 +04:00
2011-07-05 15:42:39 +04:00
static int dbwrap_null_parser ( TDB_DATA key , TDB_DATA val , void * data )
{
return 0 ;
}
2011-07-05 15:10:30 +04:00
int dbwrap_parse_record ( struct db_context * db , TDB_DATA key ,
int ( * parser ) ( TDB_DATA key , TDB_DATA data ,
void * private_data ) ,
void * private_data )
{
2011-07-05 15:42:39 +04:00
if ( parser = = NULL ) {
parser = dbwrap_null_parser ;
}
2011-12-08 16:59:33 +04:00
if ( db - > parse_record = = NULL ) {
return dbwrap_fallback_parse_record ( db , key , parser ,
private_data ) ;
2011-07-05 15:10:30 +04:00
}
2011-12-08 16:59:33 +04:00
return db - > parse_record ( db , key , parser , private_data ) ;
2011-07-05 15:10:30 +04:00
}
2011-08-16 16:39:19 +04:00
int dbwrap_wipe ( struct db_context * db )
{
2011-12-08 17:01:27 +04:00
if ( db - > wipe = = NULL ) {
return dbwrap_fallback_wipe ( db ) ;
}
2011-08-16 16:39:19 +04:00
return db - > wipe ( db ) ;
}
2011-08-18 00:43:01 +04:00
2011-08-18 16:09:56 +04:00
int dbwrap_get_seqnum ( struct db_context * db )
{
return db - > get_seqnum ( db ) ;
}
2011-08-18 00:43:01 +04:00
int dbwrap_get_flags ( struct db_context * db )
{
return db - > get_flags ( db ) ;
}
2011-08-18 00:51:12 +04:00
int dbwrap_transaction_start ( struct db_context * db )
{
return db - > transaction_start ( db ) ;
}
int dbwrap_transaction_commit ( struct db_context * db )
{
return db - > transaction_commit ( db ) ;
}
int dbwrap_transaction_cancel ( struct db_context * db )
{
return db - > transaction_cancel ( db ) ;
}