Esempio n. 1
0
void
BackupRestore::tuple(const TupleS & tup)
{
  if (!m_restore)
    return;
  while (1) 
  {
    NdbTransaction * trans = m_ndb->startTransaction();
    if (trans == NULL) 
    {
      // Deep shit, TODO: handle the error
      ndbout << "Cannot start transaction" << endl;
      exitHandler();
    } // if
    
    const TableS * table = tup.getTable();
    NdbOperation * op = trans->getNdbOperation(table->getTableName());
    if (op == NULL) 
    {
      ndbout << "Cannot get operation: ";
      ndbout << trans->getNdbError() << endl;
      exitHandler();
    } // if
    
    // TODO: check return value and handle error
    if (op->writeTuple() == -1) 
    {
      ndbout << "writeTuple call failed: ";
      ndbout << trans->getNdbError() << endl;
      exitHandler();
    } // if
    
    for (int i = 0; i < tup.getNoOfAttributes(); i++) 
    {
      const AttributeS * attr = tup[i];
      int size = attr->Desc->size;
      int arraySize = attr->Desc->arraySize;
      const char * dataPtr = attr->Data.string_value;
      
      const Uint32 length = (size * arraySize) / 8;
      if (attr->Desc->m_column->getPrimaryKey()) 
	op->equal(i, dataPtr, length);
    }
    
    for (int i = 0; i < tup.getNoOfAttributes(); i++) 
    {
      const AttributeS * attr = tup[i];
      int size = attr->Desc->size;
      int arraySize = attr->Desc->arraySize;
      const char * dataPtr = attr->Data.string_value;
      
      const Uint32 length = (size * arraySize) / 8;
      if (!attr->Desc->m_column->getPrimaryKey())
	if (attr->Data.null)
	  op->setValue(i, NULL, 0);
	else
	  op->setValue(i, dataPtr, length);
    }
    int ret = trans->execute(NdbTransaction::Commit);
    if (ret != 0)
    {
      ndbout << "execute failed: ";
      ndbout << trans->getNdbError() << endl;
      exitHandler();
    }
    m_ndb->closeTransaction(trans);
    if (ret == 0)
      break;
  }
  m_dataCount++;
}
Esempio n. 2
0
/* set all the unique attrs of this objectclass into the table
 */
extern "C" int
ndb_oc_attrs(
	NdbTransaction *txn,
	const NdbDictionary::Table *myTable,
	Entry *e,
	NdbOcInfo *no,
	NdbAttrInfo **attrs,
	int nattrs,
	Attribute *old
)
{
	char buf[65538], *ptr;
	Attribute **an, **ao, *a;
	NdbOperation *myop;
	int i, j, max = 0;
	int changed, rc;
	Uint64 eid = e->e_id;

	if ( !nattrs )
		return 0;

	an = (Attribute **)ch_malloc( 2 * nattrs * sizeof(Attribute *));
	ao = an + nattrs;

	/* Turn lists of attrs into arrays for easier access */
	for ( i=0; i<nattrs; i++ ) {
		if ( attrs[i]->na_oi != no ) {
			an[i] = NULL;
			ao[i] = NULL;
			continue;
		}
		for ( a=e->e_attrs; a; a=a->a_next ) {
			if ( a->a_desc == slap_schema.si_ad_objectClass )
				continue;
			if ( a->a_desc->ad_type == attrs[i]->na_attr ) {
				/* Don't process same attr twice */
				if ( a->a_flags & SLAP_ATTR_IXADD )
					a = NULL;
				else
					a->a_flags |= SLAP_ATTR_IXADD;
				break;
			}
		}
		an[i] = a;
		if ( a && a->a_numvals > max )
			max = a->a_numvals;
		for ( a=old; a; a=a->a_next ) {
			if ( a->a_desc == slap_schema.si_ad_objectClass )
				continue;
			if ( a->a_desc->ad_type == attrs[i]->na_attr )
				break;
		}
		ao[i] = a;
		if ( a && a->a_numvals > max )
			max = a->a_numvals;
	}

	for ( i=0; i<max; i++ ) {
		myop = NULL;
		for ( j=0; j<nattrs; j++ ) {
			if ( !an[j] && !ao[j] )
				continue;
			changed = 0;
			if ( an[j] && an[j]->a_numvals > i ) {
				/* both old and new are present, compare for changes */
				if ( ao[j] && ao[j]->a_numvals > i ) {
					if ( ber_bvcmp( &ao[j]->a_nvals[i], &an[j]->a_nvals[i] ))
						changed = V_REP;
				} else {
					changed = V_INS;
				}
			} else {
				if ( ao[j] && ao[j]->a_numvals > i )
					changed = V_DEL;
			}
			if ( changed ) {
				if ( !myop ) {
					rc = LDAP_OTHER;
					myop = txn->getNdbOperation( myTable );
					if ( !myop ) {
						goto done;
					}
					if ( old ) {
						if ( myop->writeTuple()) {
							goto done;
						}
					} else {
						if ( myop->insertTuple()) {
							goto done;
						}
					}
					if ( myop->equal( EID_COLUMN, eid )) {
						goto done;
					}
					if ( myop->equal( VID_COLUMN, i )) {
						goto done;
					}
				}
				if ( attrs[j]->na_flag & NDB_INFO_ATBLOB ) {
					NdbBlob *myBlob = myop->getBlobHandle( attrs[j]->na_column );
					rc = LDAP_OTHER;
					if ( !myBlob ) {
						Debug( LDAP_DEBUG_TRACE, "ndb_oc_attrs: getBlobHandle failed %s (%d)\n",
							myop->getNdbError().message, myop->getNdbError().code, 0 );
						goto done;
					}
					if ( slapMode & SLAP_TOOL_MODE )
						ndb_flush_blobs = 1;
					if ( changed & V_INS ) {
						if ( myBlob->setValue( an[j]->a_vals[i].bv_val, an[j]->a_vals[i].bv_len )) {
							Debug( LDAP_DEBUG_TRACE, "ndb_oc_attrs: blob->setValue failed %s (%d)\n",
								myBlob->getNdbError().message, myBlob->getNdbError().code, 0 );
							goto done;
						}
					} else {
						if ( myBlob->setValue( NULL, 0 )) {
							Debug( LDAP_DEBUG_TRACE, "ndb_oc_attrs: blob->setValue failed %s (%d)\n",
								myBlob->getNdbError().message, myBlob->getNdbError().code, 0 );
							goto done;
						}
					}
				} else {
					if ( changed & V_INS ) {
						if ( an[j]->a_vals[i].bv_len > attrs[j]->na_len ) {
							Debug( LDAP_DEBUG_ANY, "ndb_oc_attrs: attribute %s too long for column\n",
								attrs[j]->na_name.bv_val, 0, 0 );
							rc = LDAP_CONSTRAINT_VIOLATION;
							goto done;
						}
						ptr = buf;
						*ptr++ = an[j]->a_vals[i].bv_len & 0xff;
						if ( attrs[j]->na_len > 255 ) {
							/* MedVar */
							*ptr++ = an[j]->a_vals[i].bv_len >> 8;
						}
						memcpy( ptr, an[j]->a_vals[i].bv_val, an[j]->a_vals[i].bv_len );
						ptr = buf;
					} else {
						ptr = NULL;
					}
					if ( myop->setValue( attrs[j]->na_column, ptr )) {
						rc = LDAP_OTHER;
						goto done;
					}
				}
			}
		}
Esempio n. 3
0
void BackupRestore::tuple_a(restore_callback_t *cb)
{
  while (cb->retries < 10) 
  {
    /**
     * start transactions
     */
    cb->connection = m_ndb->startTransaction();
    if (cb->connection == NULL) 
    {
      if (errorHandler(cb)) 
      {
	m_ndb->sendPollNdb(3000, 1);
	continue;
      }
      exitHandler();
    } // if
    
    const TupleS &tup = cb->tup;
    const NdbDictionary::Table * table = get_table(tup.getTable()->m_dictTable);

    NdbOperation * op = cb->connection->getNdbOperation(table);
    
    if (op == NULL) 
    {
      if (errorHandler(cb)) 
	continue;
      exitHandler();
    } // if
    
    if (op->writeTuple() == -1) 
    {
      if (errorHandler(cb))
	continue;
      exitHandler();
    } // if
    
    int ret = 0;
    for (int j = 0; j < 2; j++)
    {
      for (int i = 0; i < tup.getNoOfAttributes(); i++) 
      {
	const AttributeDesc * attr_desc = tup.getDesc(i);
	const AttributeData * attr_data = tup.getData(i);
	int size = attr_desc->size;
	int arraySize = attr_desc->arraySize;
	char * dataPtr = attr_data->string_value;
	Uint32 length = (size * arraySize) / 8;

	if (j == 0 && tup.getTable()->have_auto_inc(i))
	  tup.getTable()->update_max_auto_val(dataPtr,size*arraySize);

	if (attr_desc->m_column->getPrimaryKey())
	{
	  if (j == 1) continue;
	  ret = op->equal(i, dataPtr, length);
	}
	else
	{
	  if (j == 0) continue;
	  if (attr_data->null) 
	    ret = op->setValue(i, NULL, 0);
	  else
	    ret = op->setValue(i, dataPtr, length);
	}
	if (ret < 0) {
	  ndbout_c("Column: %d type %d %d %d %d",i,
		   attr_desc->m_column->getType(),
		   size, arraySize, attr_data->size);
	  break;
	}
      }
      if (ret < 0)
	break;
    }
    if (ret < 0)
    {
      if (errorHandler(cb)) 
	continue;
      exitHandler();
    }

    // Prepare transaction (the transaction is NOT yet sent to NDB)
    cb->connection->executeAsynchPrepare(NdbTransaction::Commit,
					 &callback, cb);
    m_transactions++;
    return;
  }
  err << "Retried transaction " << cb->retries << " times.\nLast error"
      << m_ndb->getNdbError(cb->error_code) << endl
      << "...Unable to recover from errors. Exiting..." << endl;
  exitHandler();
}