示例#1
0
/**
 * Enable the closed loop controller.
 *
 * Start actually controlling the output based on the feedback.
 * If starting a position controller with an encoder reference,
 * use the encoderInitialPosition parameter to initialize the
 * encoder state.
 *
 * @param encoderInitialPosition Encoder position to set if position with encoder reference.  Ignored otherwise.
 */
void CANJaguar::EnableControl(double encoderInitialPosition)
{
    uint8_t dataBuffer[8];
    uint8_t dataSize = 0;

    switch(m_controlMode)
    {
    case kPercentVbus:
	setTransaction(LM_API_VOLT_T_EN, dataBuffer, dataSize);
	break;
    case kSpeed:
	setTransaction(LM_API_SPD_T_EN, dataBuffer, dataSize);
	break;
    case kPosition:
	dataSize = packFXP16_16(dataBuffer, encoderInitialPosition);
	setTransaction(LM_API_POS_T_EN, dataBuffer, dataSize);
	break;
    case kCurrent:
	setTransaction(LM_API_ICTRL_T_EN, dataBuffer, dataSize);
	break;
    case kVoltage:
	setTransaction(LM_API_VCOMP_T_EN, dataBuffer, dataSize);
	break;
    }
}
示例#2
0
/**
 * Configure what the controller does to the H-Bridge when neutral (not driving the output).
 *
 * This allows you to override the jumper configuration for brake or coast.
 *
 * @param mode Select to use the jumper setting or to override it to coast or brake.
 */
void CANJaguar::ConfigNeutralMode(NeutralMode mode)
{
    uint8_t dataBuffer[8];

    dataBuffer[0] = mode;
    setTransaction(LM_API_CFG_BRAKE_COAST, dataBuffer, sizeof(uint8_t));
}
示例#3
0
/**
 * Configure Soft Position Limits when in Position Controller mode.
 *
 * When controlling position, you can add additional limits on top of the limit switch inputs
 * that are based on the position feedback.  If the position limit is reached or the
 * switch is opened, that direction will be disabled.
 *
 * @param forwardLimitPosition The position that if exceeded will disable the forward direction.
 * @param reverseLimitPosition The position that if exceeded will disable the reverse direction.
 */
void CANJaguar::ConfigSoftPositionLimits(double forwardLimitPosition, double reverseLimitPosition)
{
    uint8_t dataBuffer[8];
    uint8_t dataSize;

    dataSize = packFXP16_16(dataBuffer, forwardLimitPosition);
    dataBuffer[dataSize++] = forwardLimitPosition > reverseLimitPosition;
    setTransaction(LM_API_CFG_LIMIT_FWD, dataBuffer, dataSize);

    dataSize = packFXP16_16(dataBuffer, reverseLimitPosition);
    dataBuffer[dataSize++] = forwardLimitPosition <= reverseLimitPosition;
    setTransaction(LM_API_CFG_LIMIT_REV, dataBuffer, dataSize);

    dataBuffer[0] = kLimitMode_SoftPositionLimits;
    setTransaction(LM_API_CFG_LIMIT_MODE, dataBuffer, sizeof(uint8_t));
}
示例#4
0
/**
 * Disable Soft Position Limits if previously enabled.
 *
 * Soft Position Limits are disabled by default.
 */
void CANJaguar::DisableSoftPositionLimits()
{
    uint8_t dataBuffer[8];

    dataBuffer[0] = kLimitMode_SwitchInputsOnly;
    setTransaction(LM_API_CFG_LIMIT_MODE, dataBuffer, sizeof(uint8_t));
}
示例#5
0
/**
 * Set the reference source device for speed controller mode.
 *
 * Choose encoder as the source of speed feedback when in speed control mode.
 *
 * @param reference Specify a SpeedReference.
 */
void CANJaguar::SetSpeedReference(SpeedReference reference)
{
    uint8_t dataBuffer[8];

    dataBuffer[0] = reference;
    setTransaction(LM_API_SPD_REF, dataBuffer, sizeof(uint8_t));
}
示例#6
0
/**
 * Set the reference source device for position controller mode.
 *
 * Choose between using and encoder and using a potentiometer
 * as the source of position feedback when in position control mode.
 *
 * @param reference Specify a PositionReference.
 */
void CANJaguar::SetPositionReference(PositionReference reference)
{
    uint8_t dataBuffer[8];

    dataBuffer[0] = reference;
    setTransaction(LM_API_POS_REF, dataBuffer, sizeof(uint8_t));
}
示例#7
0
  void DeclExtractor::Transform() {
    if (!getTransaction()->getCompilationOpts().DeclarationExtraction)
      return;

    if(!ExtractDecl(getTransaction()->getWrapperFD()))
      setTransaction(0); // On error set to NULL.
  }
/**
 * Configure the maximum voltage that the Jaguar will ever output.
 * 
 * This can be used to limit the maximum output voltage in all modes so that
 * motors which cannot withstand full bus voltage can be used safely.
 * 
 * @param voltage The maximum voltage output by the Jaguar.
 */
void CANJaguar::ConfigMaxOutputVoltage(double voltage)
{
	UINT8 dataBuffer[8];
	UINT8 dataSize;

	dataSize = packFXP8_8(dataBuffer, voltage);
	setTransaction(LM_API_CFG_MAX_VOUT, dataBuffer, dataSize);
}
/**
 * Configure the number of turns on the potentiometer.
 * 
 * There is no special support for continuous turn potentiometers.
 * Only integer numbers of turns are supported.
 * 
 * @param turns The number of turns of the potentiometer
 */
void CANJaguar::ConfigPotentiometerTurns(UINT16 turns)
{
	UINT8 dataBuffer[8];
	UINT8 dataSize;

	dataSize = packINT16(dataBuffer, turns);
	setTransaction(LM_API_CFG_POT_TURNS, dataBuffer, dataSize);
}
/**
 * Configure how many codes per revolution are generated by your encoder.
 * 
 * @param codesPerRev The number of counts per revolution in 1X mode.
 */
void CANJaguar::ConfigEncoderCodesPerRev(UINT16 codesPerRev)
{
	UINT8 dataBuffer[8];
	UINT8 dataSize;

	dataSize = packINT16(dataBuffer, codesPerRev);
	setTransaction(LM_API_CFG_ENC_LINES, dataBuffer, dataSize);
}
  void ValuePrinterSynthesizer::Transform() {
    if (getTransaction()->getCompilationOpts().ValuePrinting 
        == CompilationOptions::VPDisabled)
      return;

    if (!tryAttachVP(getTransaction()->getWrapperFD()))
      return setTransaction(0); // On error set to NULL.
  }
示例#12
0
/**
 * Configure how many codes per revolution are generated by your encoder.
 *
 * @param codesPerRev The number of counts per revolution in 1X mode.
 */
void CANJaguar::ConfigEncoderCodesPerRev(uint16_t codesPerRev)
{
    uint8_t dataBuffer[8];
    uint8_t dataSize;

    dataSize = packint16_t(dataBuffer, codesPerRev);
    setTransaction(LM_API_CFG_ENC_LINES, dataBuffer, dataSize);
}
示例#13
0
/**
 * Configure the number of turns on the potentiometer.
 *
 * There is no special support for continuous turn potentiometers.
 * Only integer numbers of turns are supported.
 *
 * @param turns The number of turns of the potentiometer
 */
void CANJaguar::ConfigPotentiometerTurns(uint16_t turns)
{
    uint8_t dataBuffer[8];
    uint8_t dataSize;

    dataSize = packint16_t(dataBuffer, turns);
    setTransaction(LM_API_CFG_POT_TURNS, dataBuffer, dataSize);
}
/**
 * Configure how long the Jaguar waits in the case of a fault before resuming operation.
 * 
 * Faults include over temerature, over current, and bus under voltage.
 * The default is 3.0 seconds, but can be reduced to as low as 0.5 seconds.
 * 
 * @param faultTime The time to wait before resuming operation, in seconds.
 */
void CANJaguar::ConfigFaultTime(float faultTime)
{
	UINT8 dataBuffer[8];
	UINT8 dataSize;

	// Message takes ms
	dataSize = packINT16(dataBuffer, (INT16)(faultTime * 1000.0));
	setTransaction(LM_API_CFG_FAULT_TIME, dataBuffer, dataSize);
}
示例#15
0
/**
 * Configure how long the Jaguar waits in the case of a fault before resuming operation.
 *
 * Faults include over temerature, over current, and bus under voltage.
 * The default is 3.0 seconds, but can be reduced to as low as 0.5 seconds.
 *
 * @param faultTime The time to wait before resuming operation, in seconds.
 */
void CANJaguar::ConfigFaultTime(float faultTime)
{
    uint8_t dataBuffer[8];
    uint8_t dataSize;

    // Message takes ms
    dataSize = packint16_t(dataBuffer, (int16_t)(faultTime * 1000.0));
    setTransaction(LM_API_CFG_FAULT_TIME, dataBuffer, dataSize);
}
示例#16
0
/**
 * Set the output set-point value.
 *
 * The scale and the units depend on the mode the Jaguar is in.
 * In PercentVbus Mode, the outputValue is from -1.0 to 1.0 (same as PWM Jaguar).
 * In Voltage Mode, the outputValue is in Volts.
 * In Current Mode, the outputValue is in Amps.
 * In Speed Mode, the outputValue is in Rotations/Minute.
 * In Position Mode, the outputValue is in Rotations.
 *
 * @param outputValue The set-point to sent to the motor controller.
 * @param syncGroup The update group to add this Set() to, pending UpdateSyncGroup().  If 0, update immediately.
 */
void CANJaguar::Set(float outputValue, uint8_t syncGroup)
{
    uint32_t messageID;
    uint8_t dataBuffer[8];
    uint8_t dataSize;

    if (m_safetyHelper && !m_safetyHelper->IsAlive())
    {
	EnableControl();
    }

    switch(m_controlMode)
    {
    case kPercentVbus:
	{
	    messageID = LM_API_VOLT_T_SET;
	    if (outputValue > 1.0) outputValue = 1.0;
	    if (outputValue < -1.0) outputValue = -1.0;
	    dataSize = packPercentage(dataBuffer, outputValue);
	}
	break;
    case kSpeed:
	{
	    messageID = LM_API_SPD_T_SET;
	    dataSize = packFXP16_16(dataBuffer, outputValue);
	}
	break;
    case kPosition:
	{
	    messageID = LM_API_POS_T_SET;
	    dataSize = packFXP16_16(dataBuffer, outputValue);
	}
	break;
    case kCurrent:
	{
	    messageID = LM_API_ICTRL_T_SET;
	    dataSize = packFXP8_8(dataBuffer, outputValue);
	}
	break;
    case kVoltage:
	{
	    messageID = LM_API_VCOMP_T_SET;
	    dataSize = packFXP8_8(dataBuffer, outputValue);
	}
	break;
    default:
	return;
    }
    if (syncGroup != 0)
    {
	dataBuffer[dataSize] = syncGroup;
	dataSize++;
    }
    setTransaction(messageID, dataBuffer, dataSize);
    if (m_safetyHelper) m_safetyHelper->Feed();
}
示例#17
0
/**
 * Set the maximum voltage change rate.
 *
 * When in PercentVbus or Voltage output mode, the rate at which the voltage changes can
 * be limited to reduce current spikes.  Set this to 0.0 to disable rate limiting.
 *
 * @param rampRate The maximum rate of voltage change in Percent Voltage mode in V/s.
 */
void CANJaguar::SetVoltageRampRate(double rampRate)
{
    uint8_t dataBuffer[8];
    uint8_t dataSize;

    switch(m_controlMode)
    {
    case kPercentVbus:
	dataSize = packPercentage(dataBuffer, rampRate / (m_maxOutputVoltage * kControllerRate));
	setTransaction(LM_API_VOLT_SET_RAMP, dataBuffer, dataSize);
	break;
    case kVoltage:
	dataSize = packFXP8_8(dataBuffer, rampRate / kControllerRate);
	setTransaction(LM_API_VCOMP_IN_RAMP, dataBuffer, dataSize);
	break;
    default:
	return;
    }
}
ResponseHandler* RequestHandlerAdaptor::newPushedResponse(
  PushHandler* pushHandler) noexcept {
  auto pushTxn = txn_->newPushedTransaction(pushHandler->getHandler());
  if (!pushTxn) {
    // Codec doesn't support push
    return nullptr;
  }
  auto pushHandlerAdaptor = new RequestHandlerAdaptor(pushHandler);
  pushHandlerAdaptor->setTransaction(pushTxn);
  return pushHandlerAdaptor;
}
示例#19
0
void PkInstallProvideFiles::search()
{
    PkTransaction *transaction = new PkTransaction(this);
    transaction->setupTransaction(Daemon::searchFiles(m_args,
                                                      Transaction::FilterArch | Transaction::FilterNewest));
    setTransaction(Transaction::RoleSearchFile, transaction);
    connect(transaction, SIGNAL(finished(PkTransaction::ExitStatus)),
            this, SLOT(searchFinished(PkTransaction::ExitStatus)), Qt::UniqueConnection);
    connect(transaction, SIGNAL(package(PackageKit::Transaction::Info,QString,QString)),
            this, SLOT(addPackage(PackageKit::Transaction::Info,QString,QString)));
}
示例#20
0
  void DeclExtractor::Transform() {
    if (!getTransaction()->getCompilationOpts().DeclarationExtraction)
      return;

    for (Transaction::const_iterator I = getTransaction()->decls_begin(), 
           E = getTransaction()->decls_end(); I != E; ++I)
      for (DeclGroupRef::const_iterator J = (*I).begin(), 
             JE = (*I).end(); J != JE; ++J)
        if(!ExtractDecl(*J))
          setTransaction(0); // On error set to NULL.
  }
/**
 * Disable the closed loop controller.
 * 
 * Stop driving the output based on the feedback.
 */
void CANJaguar::DisableControl()
{
	UINT8 dataBuffer[8];
	UINT8 dataSize = 0;

	switch(m_controlMode)
	{
	case kPercentVoltage:
		// TODO: Error, Not Valid
		break;
	case kSpeed:
		setTransaction(LM_API_SPD_DIS, dataBuffer, dataSize);
		break;
	case kPosition:
		setTransaction(LM_API_POS_DIS, dataBuffer, dataSize);
		break;
	case kCurrent:
		setTransaction(LM_API_ICTRL_DIS, dataBuffer, dataSize);
		break;
	}
}
/**
 * Enable the closed loop controller.
 * 
 * Start actually controlling the output based on the feedback.
 * If starting a position controller with an encoder reference,
 * use the encoderInitialPosition parameter to initialize the
 * encoder state.
 * 
 * @param encoderInitialPosition Encoder position to set if position with encoder reference.  Ignored otherwise.
 */
void CANJaguar::EnableControl(double encoderInitialPosition)
{
	UINT8 dataBuffer[8];
	UINT8 dataSize = 0;

	switch(m_controlMode)
	{
	case kPercentVoltage:
		// TODO: Error, Not Valid
		break;
	case kSpeed:
		setTransaction(LM_API_SPD_T_EN, dataBuffer, dataSize);
		break;
	case kPosition:
		dataSize = packFXP16_16(dataBuffer, encoderInitialPosition);
		setTransaction(LM_API_POS_T_EN, dataBuffer, dataSize);
		break;
	case kCurrent:
		setTransaction(LM_API_ICTRL_T_EN, dataBuffer, dataSize);
		break;
	}
}
/**
 * Set the reference source device for position controller mode.
 * 
 * Choose between using and encoder and using a potentiometer
 * as the source of position feedback when in position control mode.
 * 
 * @param reference Specify a PositionReference.
 */
void CANJaguar::SetPositionReference(PositionReference reference)
{
	UINT8 dataBuffer[8];

	switch(m_controlMode)
	{
	case kPosition:
		dataBuffer[0] = reference;
		setTransaction(LM_API_POS_REF, dataBuffer, sizeof(UINT8));
		break;
	default:
		// TODO: Error, Invalid
		return;
	}
}
示例#24
0
/**
 * Disable the closed loop controller.
 *
 * Stop driving the output based on the feedback.
 */
void CANJaguar::DisableControl()
{
    uint8_t dataBuffer[8];
    uint8_t dataSize = 0;

    switch(m_controlMode)
    {
    case kPercentVbus:
	setTransaction(LM_API_VOLT_DIS, dataBuffer, dataSize);
	break;
    case kSpeed:
	setTransaction(LM_API_SPD_DIS, dataBuffer, dataSize);
	break;
    case kPosition:
	setTransaction(LM_API_POS_DIS, dataBuffer, dataSize);
	break;
    case kCurrent:
	setTransaction(LM_API_ICTRL_DIS, dataBuffer, dataSize);
	break;
    case kVoltage:
	setTransaction(LM_API_VCOMP_DIS, dataBuffer, dataSize);
	break;
    }
}
/**
 * Set the maximum voltage change rate.
 * 
 * When in percent voltage output mode, the rate at which the voltage changes can
 * be limited to reduce current spikes.  Set this to 0.0 to disable rate limiting.
 * 
 * @param rampRate The maximum rate of voltage change in Percent Voltage mode in V/s.
 */
void CANJaguar::SetVoltageRampRate(double rampRate)
{
	UINT8 dataBuffer[8];
	UINT8 dataSize;

	switch(m_controlMode)
	{
	case kPercentVoltage:
		dataSize = packPercentage(dataBuffer, rampRate / (kApproxBusVoltage * kApproxBusVoltage));
		setTransaction(LM_API_VOLT_SET_RAMP, dataBuffer, dataSize);
		break;
	default:
		return;
	}
}
示例#26
0
/**
 * Set the P, I, and D constants for the closed loop modes.
 *
 * @param p The proportional gain of the Jaguar's PID controller.
 * @param i The integral gain of the Jaguar's PID controller.
 * @param d The differential gain of the Jaguar's PID controller.
 */
void CANJaguar::SetPID(double p, double i, double d)
{
    uint8_t dataBuffer[8];
    uint8_t dataSize;

    switch(m_controlMode)
    {
    case kPercentVbus:
    case kVoltage:
	wpi_setWPIErrorWithContext(IncompatibleMode, "PID constants only apply in Speed, Position, and Current mode");
	break;
    case kSpeed:
	dataSize = packFXP16_16(dataBuffer, p);
	setTransaction(LM_API_SPD_PC, dataBuffer, dataSize);
	dataSize = packFXP16_16(dataBuffer, i);
	setTransaction(LM_API_SPD_IC, dataBuffer, dataSize);
	dataSize = packFXP16_16(dataBuffer, d);
	setTransaction(LM_API_SPD_DC, dataBuffer, dataSize);
	break;
    case kPosition:
	dataSize = packFXP16_16(dataBuffer, p);
	setTransaction(LM_API_POS_PC, dataBuffer, dataSize);
	dataSize = packFXP16_16(dataBuffer, i);
	setTransaction(LM_API_POS_IC, dataBuffer, dataSize);
	dataSize = packFXP16_16(dataBuffer, d);
	setTransaction(LM_API_POS_DC, dataBuffer, dataSize);
	break;
    case kCurrent:
	dataSize = packFXP16_16(dataBuffer, p);
	setTransaction(LM_API_ICTRL_PC, dataBuffer, dataSize);
	dataSize = packFXP16_16(dataBuffer, i);
	setTransaction(LM_API_ICTRL_IC, dataBuffer, dataSize);
	dataSize = packFXP16_16(dataBuffer, d);
	setTransaction(LM_API_ICTRL_DC, dataBuffer, dataSize);
	break;
    }
}
/**
 * Check if the Jaguar's power has been cycled since this was last called.
 * 
 * This should return true the first time called after a Jaguar power up,
 * and false after that.
 * 
 * @return The Jaguar was power cycled since the last call to this function.
 */
bool CANJaguar::GetPowerCycled()
{
	UINT8 dataBuffer[8];
	UINT8 dataSize;

	getTransaction(LM_API_STATUS_POWER, dataBuffer, &dataSize);
	if (dataSize == sizeof(UINT8))
	{
		bool powerCycled = (*dataBuffer != 0);

		// Clear the power cycled bit now that we've accessed it
		dataBuffer[0] = 1;
		setTransaction(LM_API_STATUS_POWER, dataBuffer, sizeof(UINT8));

		return powerCycled;
	}
	return 0;
}
示例#28
0
/**
 * Set the P, I, and D constants for the closed loop modes.
 * 
 * @param p The proportional gain of the Jaguar's PID controller.
 * @param i The integral gain of the Jaguar's PID controller.
 * @param d The differential gain of the Jaguar's PID controller.
 */
void CANJaguar::SetPID(double p, double i, double d)
{
	UINT8 dataBuffer[8];
	UINT8 dataSize;

	switch(m_controlMode)
	{
	case kPercentVbus:
	case kVoltage:
		// TODO: Error, Not Valid
		break;
	case kSpeed:
		dataSize = packFXP16_16(dataBuffer, p);
		setTransaction(LM_API_SPD_PC, dataBuffer, dataSize);
		dataSize = packFXP16_16(dataBuffer, i);
		setTransaction(LM_API_SPD_IC, dataBuffer, dataSize);
		dataSize = packFXP16_16(dataBuffer, d);
		setTransaction(LM_API_SPD_DC, dataBuffer, dataSize);
		break;
	case kPosition:
		dataSize = packFXP16_16(dataBuffer, p);
		setTransaction(LM_API_POS_PC, dataBuffer, dataSize);
		dataSize = packFXP16_16(dataBuffer, i);
		setTransaction(LM_API_POS_IC, dataBuffer, dataSize);
		dataSize = packFXP16_16(dataBuffer, d);
		setTransaction(LM_API_POS_DC, dataBuffer, dataSize);
		break;
	case kCurrent:
		dataSize = packFXP16_16(dataBuffer, p);
		setTransaction(LM_API_ICTRL_PC, dataBuffer, dataSize);
		dataSize = packFXP16_16(dataBuffer, i);
		setTransaction(LM_API_ICTRL_IC, dataBuffer, dataSize);
		dataSize = packFXP16_16(dataBuffer, d);
		setTransaction(LM_API_ICTRL_DC, dataBuffer, dataSize);
		break;
	}
}
/**
 * Set the output set-point value.  
 * 
 * In PercentVoltage Mode, the input is in the range -1.0 to 1.0
 * 
 * @param outputValue The set-point to sent to the motor controller.
 */
void CANJaguar::Set(float outputValue)
{
	UINT32 messageID;
	UINT8 dataBuffer[8];
	UINT8 dataSize;

	switch(m_controlMode)
	{
	case kPercentVoltage:
		{
			messageID = LM_API_VOLT_T_SET;
			dataSize = packPercentage(dataBuffer, outputValue);
		}
		break;
	case kSpeed:
		{
			messageID = LM_API_SPD_T_SET;
			dataSize = packFXP16_16(dataBuffer, outputValue);
		}
		break;
	case kPosition:
		{
			messageID = LM_API_POS_T_SET;
			dataSize = packFXP16_16(dataBuffer, outputValue);
		}
		break;
	case kCurrent:
		{
			messageID = LM_API_ICTRL_T_SET;
			dataSize = packFXP8_8(dataBuffer, outputValue);
		}
		break;
	default:
		return;
	}
	setTransaction(messageID, dataBuffer, dataSize);
}
示例#30
0
文件: delete.cpp 项目: aox/aox
void Delete::execute()
{
    if ( state() != Executing || !ok() )
        return;

    if ( d->first ) {
        d->first = false;

        // We should really require DeleteMessages and Expunge only if
        // we know the mailbox isn't empty; but we'll know that inside
        // the transaction, and permitted() won't let us clean that up
        // if we don't have permission. So it'll have to wait until we
        // query permissions ourselves.

        requireRight( d->m, Permissions::DeleteMailbox );
        requireRight( d->m, Permissions::DeleteMessages );
        requireRight( d->m, Permissions::Expunge );
    }

    if ( !permitted() )
        return;

    if ( !transaction() ) {
        setTransaction( new Transaction( this ) );
        Query * lock = new Query( "select * from mailboxes "
                                  "where id=$1 for update", 0 );
        lock->bind( 1, d->m->id() );
        transaction()->enqueue( lock );

        d->messages = new Query( "select count(mm.uid)::bigint as messages "
                                 "from mailbox_messages mm "
                                 "join messages m on (mm.message=m.id) "
                                 "join mailboxes mb on (mm.mailbox=mb.id) "
                                 "where mm.mailbox=$1 and not mm.seen and "
                                 "(mm.uid>=mb.first_recent or m.idate>$2)",
                                 this );
        d->messages->bind( 1, d->m->id() );
        Date now;
        now.setCurrentTime();
        d->messages->bind( 2, now.unixTime() - 20 );
        transaction()->enqueue( d->messages );
        transaction()->execute();
    }

    if ( d->messages ) {
        if ( !d->messages->done() )
            return;

        int64 messages = 0;

        Row * r = d->messages->nextRow();
        if ( d->messages->failed() || !r )
            error( No, "Could not determine if any messages exist" );
        else
            messages = r->getBigint( "messages" );

        if ( messages )
            error( No, "Cannot delete mailbox: " + fn( messages ) +
                   " messages exist" );
        d->messages = 0;

        if ( ok() && d->m->remove( transaction() ) == 0 )
            error( No, "Cannot delete mailbox " + d->m->name().ascii() );

        Mailbox::refreshMailboxes( transaction() );
        transaction()->commit();
    }

    if ( !transaction()->done() )
        return;

    if ( transaction()->failed() ) {
        error( No, "Database error: " + transaction()->error() );
        return;
    }

    finish();
}