?? db_server_cxxproc.cpp
字號:
{ Db *dbp; Dbc **jcurs, **c; Dbc *dbc; ct_entry *dbc_ctp, *ctp, *dbp_ctp; size_t size; u_int32_t *cl, i; int ret; ACTIVATE_CTP(dbp_ctp, dbpcl_id, CT_DB); dbp = (Db *)dbp_ctp->ct_anyp; dbc_ctp = new_ct_ent(&replyp->status); if (dbc_ctp == NULL) return; size = (curslen + 1) * sizeof(Dbc *); if ((ret = __os_calloc(dbp->get_DB()->dbenv, curslen + 1, sizeof(Dbc *), &jcurs)) != 0) { replyp->status = ret; __dbclear_ctp(dbc_ctp); return; } /* * If our curslist has a parent txn, we need to use it too * for the activity timeout. All cursors must be part of * the same transaction, so just check the first. */ ctp = get_tableent(*curs); DB_ASSERT(ctp->ct_type == CT_CURSOR); /* * If we are using a transaction, set the join activity timer * to point to the parent transaction. */ if (ctp->ct_activep != &ctp->ct_active) dbc_ctp->ct_activep = ctp->ct_activep; for (i = 0, cl = curs, c = jcurs; i < curslen; i++, cl++, c++) { ctp = get_tableent(*cl); if (ctp == NULL) { replyp->status = DB_NOSERVER_ID; goto out; } /* * If we are using a txn, the join cursor points to the * transaction timeout. If we are not using a transaction, * then all the curslist cursors must point to the join * cursor's timeout so that we do not timeout any of the * curlist cursors while the join cursor is active. * Change the type of the curslist ctps to CT_JOIN so that * we know they are part of a join list and we can distinguish * them and later restore them when the join cursor is closed. */ DB_ASSERT(ctp->ct_type == CT_CURSOR); ctp->ct_type |= CT_JOIN; ctp->ct_origp = ctp->ct_activep; /* * Setting this to the ct_active field of the dbc_ctp is * really just a way to distinguish which join dbc this * cursor is part of. The ct_activep of this cursor is * not used at all during its lifetime as part of a join * cursor. */ ctp->ct_activep = &dbc_ctp->ct_active; *c = ctp->ct_dbc; } *c = NULL; if ((ret = dbp->join(jcurs, &dbc, flags)) == 0) { dbc_ctp->ct_dbc = dbc; dbc_ctp->ct_type = (CT_JOINCUR | CT_CURSOR); dbc_ctp->ct_parent = dbp_ctp; dbc_ctp->ct_envparent = dbp_ctp->ct_envparent; __dbsrv_settimeout(dbc_ctp, dbp_ctp->ct_envparent->ct_timeout); __dbsrv_active(dbc_ctp); replyp->dbcidcl_id = dbc_ctp->ct_id; } else { __dbclear_ctp(dbc_ctp); /* * If we get an error, undo what we did above to any cursors. */ for (cl = curs; *cl != 0; cl++) { ctp = get_tableent(*cl); ctp->ct_type = CT_CURSOR; ctp->ct_activep = ctp->ct_origp; } } replyp->status = ret;out: __os_free(dbp->get_DB()->dbenv, jcurs); return;}/* BEGIN __dbc_close_proc */extern "C" void__dbc_close_proc( long dbccl_id, __dbc_close_reply *replyp)/* END __dbc_close_proc */{ ct_entry *dbc_ctp; ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); replyp->status = __dbc_close_int(dbc_ctp); return;}/* BEGIN __dbc_count_proc */extern "C" void__dbc_count_proc( long dbccl_id, u_int32_t flags, __dbc_count_reply *replyp)/* END __dbc_count_proc */{ Dbc *dbc; ct_entry *dbc_ctp; db_recno_t num; int ret; ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); dbc = (Dbc *)dbc_ctp->ct_anyp; ret = dbc->count(&num, flags); replyp->status = ret; if (ret == 0) replyp->dupcount = num; return;}/* BEGIN __dbc_del_proc */extern "C" void__dbc_del_proc( long dbccl_id, u_int32_t flags, __dbc_del_reply *replyp)/* END __dbc_del_proc */{ Dbc *dbc; ct_entry *dbc_ctp; int ret; ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); dbc = (Dbc *)dbc_ctp->ct_anyp; ret = dbc->del(flags); replyp->status = ret; return;}/* BEGIN __dbc_dup_proc */extern "C" void__dbc_dup_proc( long dbccl_id, u_int32_t flags, __dbc_dup_reply *replyp)/* END __dbc_dup_proc */{ Dbc *dbc, *newdbc; ct_entry *dbc_ctp, *new_ctp; int ret; ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); dbc = (Dbc *)dbc_ctp->ct_anyp; new_ctp = new_ct_ent(&replyp->status); if (new_ctp == NULL) return; if ((ret = dbc->dup(&newdbc, flags)) == 0) { new_ctp->ct_dbc = newdbc; new_ctp->ct_type = CT_CURSOR; new_ctp->ct_parent = dbc_ctp->ct_parent; new_ctp->ct_envparent = dbc_ctp->ct_envparent; /* * If our cursor has a parent txn, we need to use it too. */ if (dbc_ctp->ct_activep != &dbc_ctp->ct_active) new_ctp->ct_activep = dbc_ctp->ct_activep; __dbsrv_settimeout(new_ctp, dbc_ctp->ct_timeout); __dbsrv_active(new_ctp); replyp->dbcidcl_id = new_ctp->ct_id; } else __dbclear_ctp(new_ctp); replyp->status = ret; return;}/* BEGIN __dbc_get_proc */extern "C" void__dbc_get_proc( long dbccl_id, u_int32_t keydlen, u_int32_t keydoff, u_int32_t keyulen, u_int32_t keyflags, void *keydata, u_int32_t keysize, u_int32_t datadlen, u_int32_t datadoff, u_int32_t dataulen, u_int32_t dataflags, void *datadata, u_int32_t datasize, u_int32_t flags, __dbc_get_reply *replyp, int * freep)/* END __dbc_get_proc */{ Dbc *dbc; DbEnv *dbenv; ct_entry *dbc_ctp; int key_alloc, bulk_alloc, ret; void *tmpdata; ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); dbc = (Dbc *)dbc_ctp->ct_anyp; dbenv = DbEnv::get_DbEnv(((DBC *)dbc)->dbp->dbenv); *freep = 0; bulk_alloc = 0; /* Set up key and data */ Dbt key(keydata, keysize); key.set_dlen(keydlen); key.set_ulen(keyulen); key.set_doff(keydoff); key.set_flags(DB_DBT_MALLOC | (keyflags & DB_DBT_PARTIAL)); Dbt data(datadata, datasize); data.set_dlen(datadlen); data.set_ulen(dataulen); data.set_doff(datadoff); dataflags &= DB_DBT_PARTIAL; if (flags & DB_MULTIPLE || flags & DB_MULTIPLE_KEY) { if (data.get_data() == NULL) { ret = __os_umalloc(dbenv->get_DB_ENV(), data.get_ulen(), &tmpdata); if (ret != 0) goto err; data.set_data(tmpdata); bulk_alloc = 1; } dataflags |= DB_DBT_USERMEM; } else dataflags |= DB_DBT_MALLOC; data.set_flags(dataflags); /* Got all our stuff, now do the get */ ret = dbc->get(&key, &data, flags); /* * Otherwise just status. */ if (ret == 0) { /* * XXX * We need to xdr_free whatever we are returning, next time. * However, DB does not allocate a new key if one was given * and we'd be free'ing up space allocated in the request. * So, allocate a new key/data pointer if it is the same one * as in the request. */ *freep = 1; /* * Key */ key_alloc = 0; if (key.get_data() == keydata) { ret = __os_umalloc(dbenv->get_DB_ENV(), key.get_size(), &replyp->keydata.keydata_val); if (ret != 0) { __os_ufree(dbenv->get_DB_ENV(), key.get_data()); __os_ufree(dbenv->get_DB_ENV(), data.get_data()); goto err; } key_alloc = 1; memcpy(replyp->keydata.keydata_val, key.get_data(), key.get_size()); } else replyp->keydata.keydata_val = (char *)key.get_data(); replyp->keydata.keydata_len = key.get_size(); /* * Data */ if (data.get_data() == datadata) { ret = __os_umalloc(dbenv->get_DB_ENV(), data.get_size(), &replyp->datadata.datadata_val); if (ret != 0) { __os_ufree(dbenv->get_DB_ENV(), key.get_data()); __os_ufree(dbenv->get_DB_ENV(), data.get_data()); if (key_alloc) __os_ufree(dbenv->get_DB_ENV(), replyp->keydata.keydata_val); goto err; } memcpy(replyp->datadata.datadata_val, data.get_data(), data.get_size()); } else replyp->datadata.datadata_val = (char *)data.get_data(); replyp->datadata.datadata_len = data.get_size(); } else {err: replyp->keydata.keydata_val = NULL; replyp->keydata.keydata_len = 0; replyp->datadata.datadata_val = NULL; replyp->datadata.datadata_len = 0; *freep = 0; if (bulk_alloc) __os_ufree(dbenv->get_DB_ENV(), data.get_data()); } replyp->status = ret; return;}/* BEGIN __dbc_pget_proc */extern "C" void__dbc_pget_proc( long dbccl_id, u_int32_t skeydlen, u_int32_t skeydoff, u_int32_t skeyulen, u_int32_t skeyflags, void *skeydata, u_int32_t skeysize, u_int32_t pkeydlen, u_int32_t pkeydoff, u_int32_t pkeyulen, u_int32_t pkeyflags, void *pkeydata, u_int32_t pkeysize, u_int32_t datadlen, u_int32_t datadoff, u_int32_t dataulen, u_int32_t dataflags, void *datadata, u_int32_t datasize, u_int32_t flags, __dbc_pget_reply *replyp, int * freep)/* END __dbc_pget_proc */{ Dbc *dbc; DbEnv *dbenv; ct_entry *dbc_ctp; int key_alloc, ret; ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); dbc = (Dbc *)dbc_ctp->ct_anyp; dbenv = DbEnv::get_DbEnv(((DBC *)dbc)->dbp->dbenv); *freep = 0; /* * Ignore memory related flags on server. */ /* Set up key and data */ Dbt skey(skeydata, skeysize); skey.set_dlen(skeydlen); skey.set_ulen(skeyulen); skey.set_doff(skeydoff); skey.set_flags(DB_DBT_MALLOC | (skeyflags & DB_DBT_PARTIAL)); Dbt pkey(pkeydata, pkeysize); pkey.set_dlen(pkeydlen); pkey.set_ulen(pkeyulen); pkey.set_doff(pkeydoff); pkey.set_flags(DB_DBT_MALLOC | (pkeyflags & DB_DBT_PARTIAL)); Dbt data(datadata, datasize); data.set_dlen(datadlen); data.set_ulen(dataulen); data.set_doff(datadoff); data.set_flags(DB_DBT_MALLOC | (dataflags & DB_DBT_PARTIAL)); /* Got all our stuff, now do the get */ ret = dbc->pget(&skey, &pkey, &data, flags); /* * Otherwise just status. */ if (ret == 0) { /* * XXX * We need to xdr_free whatever we are returning, next time. * However, DB does not allocate a new key if one was given * and we'd be free'ing up space allocated in the request. * So, allocate a new key/data pointer if it is the same one * as in the request. */ *freep = 1; /* * Key */ key_alloc = 0; if (skey.get_data() == skeydata) { ret = __os_umalloc(dbenv->get_DB_ENV(), skey.get_size(), &replyp->skeydata.skeydata_val); if (ret != 0) { __os_ufree(dbenv->get_DB_ENV(), skey.get_data()); __os_ufree(dbenv->get_DB_ENV(), pkey.get_data()); __os_ufree(dbenv->get_DB_ENV(), data.get_data()); goto err; } key_alloc = 1; memcpy(replyp->skeydata.skeydata_val, skey.get_data(), skey.get_size()); } else replyp->skeydata.skeydata_val = (char *)skey.get_data(); replyp->skeydata.skeydata_len = skey.get_size(); /* * Primary key */ if (pkey.get_data() == pkeydata) { ret = __os_umalloc(dbenv->get_DB_ENV(), pkey.get_size(), &replyp->pkeydata.pkeydata_val); if (ret != 0) { __os_ufree(dbenv->get_DB_ENV(), skey.get_data()); __os_ufree(dbenv->get_DB_ENV(), pkey.get_data()); __os_ufree(dbenv->get_DB_ENV(), data.get_data()); if (key_alloc) __os_ufree(dbenv->get_DB_ENV(), replyp->skeydata.skeydata_val); goto err; } /* * We can set it to 2, because they cannot send the * pkey over without sending the skey over too. * So if they did send a pkey, they must have sent * the skey as well. */ key_alloc = 2; memcpy(replyp->pkeydata.pkeydata_val, pkey.get_data(), pkey.get_size()); } else replyp->pkeydata.pkeydata_val = (char *)pkey.get_data(); replyp->pkeydata.pkeydata_len = pkey.get_size(); /* * Data */ if (data.get_data() == datadata) { ret = __os_umalloc(dbenv->get_DB_ENV(), data.get_size(), &replyp->datadata.datadata_val); if (ret != 0) { __os_ufree(dbenv->get_DB_ENV(), skey.get_data()); __os_ufree(dbenv->get_DB_ENV(), pkey.get_data()); __os_ufree(dbenv->get_DB_ENV(), data.get_data()); /* * If key_alloc is 1, just skey needs to be * freed, if key_alloc is 2, both skey and pkey * need to be freed. */ if (key_alloc--) __os_ufree(dbenv->get_DB_ENV(), replyp->skeydata.skeydata_val); if (key_alloc) __os_ufree(dbenv->get_DB_ENV(), replyp->pkeydata.pkeydata_val); goto err; } memcpy(replyp->datadata.datadata_val, data.get_data(), data.get_size()); } else replyp->datadata.datadata_val = (char *)data.get_data(); replyp->datadata.datadata_len = data.get_size(); } else {err: replyp->skeydata.skeydata_val = NULL; replyp->skeydata.skeydata_len = 0; replyp->pkeydata.pkeydata_val = NULL; replyp->pkeydata.pkeydata_len = 0; replyp->datadata.datadata_val = NULL; replyp->datadata.datadata_len = 0; *freep = 0; } replyp->status = ret; return;}/* BEGIN __dbc_put_proc */extern "C" void__dbc_put_proc( long dbccl_id, u_int32_t keydlen, u_int32_t keydoff, u_int32_t keyulen, u_int32_t keyflags, void *keydata, u_int32_t keysize, u_int32_t datadlen, u_int32_t datadoff, u_int32_t dataulen, u_int32_t dataflags, void *datadata, u_int32_t datasize, u_int32_t flags, __dbc_put_reply *replyp, int * freep)/* END __dbc_put_proc */{ Db *dbp; Dbc *dbc; ct_entry *dbc_ctp; int ret; DBTYPE dbtype; ACTIVATE_CTP(dbc_ctp, dbccl_id, CT_CURSOR); dbc = (Dbc *)dbc_ctp->ct_anyp; dbp = (Db *)dbc_ctp->ct_parent->ct_anyp; /* Set up key and data */ Dbt key(keydata, keysize); key.set_dlen(keydlen); key.set_ulen(keyulen); key.set_doff(keydoff); /* * Ignore memory related flags on server. */ key.set_flags(DB_DBT_MALLOC | (keyflags & DB_DBT_PARTIAL)); Dbt data(datadata, datasize); data.set_dlen(datadlen); data.set_ulen(dataulen); data.set_doff(datadoff); data.set_flags(dataflags); /* Got all our stuff, now do the put */ ret = dbc->put(&key, &data, flags); *freep = 0; replyp->keydata.keydata_val = NULL; replyp->keydata.keydata_len = 0; if (ret == 0 && (flags == DB_AFTER || flags == DB_BEFORE)) { ret = dbp->get_type(&dbtype); if (ret == 0 && dbtype == DB_RECNO) { /* * We need to xdr_free whatever we are returning, next time. */ replyp->keydata.keydata_val = (char *)key.get_data(); replyp->keydata.keydata_len = key.get_size(); } } replyp->status = ret; return;}#endif /* HAVE_RPC */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -