<commit_before>/*
* Copyright 2008, 2009 Free Software Foundation, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	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 Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

//#define NDEBUG
#include "radioInterface.h"
#include <Logger.h>

GSM::Time VectorQueue::nextTime() const
{
  GSM::Time retVal;
  ScopedLock lock(mLock);
  while (mQ.size()==0) mWriteSignal.wait(mLock);
  return mQ.top()->time();
}

radioVector* VectorQueue::getStaleBurst(const GSM::Time& targTime)
{
  ScopedLock lock(mLock);
  if ((mQ.size()==0)) {
    return NULL;
  }
  if (mQ.top()->time() < targTime) {
    radioVector* retVal = mQ.top();
    mQ.pop();
    return retVal;
  }
  return NULL;
}

radioVector* VectorQueue::getCurrentBurst(const GSM::Time& targTime)
{
  ScopedLock lock(mLock);
  if ((mQ.size()==0)) {
    return NULL;
  }
  if (mQ.top()->time() == targTime) {
    radioVector* retVal = mQ.top();
    mQ.pop();
    return retVal;
  }
  return NULL;
}

RadioInterface::RadioInterface(RadioDevice *wRadio,
                               int wReceiveOffset,
			       int wRadioOversampling,
			       int wTransceiverOversampling,
			       GSM::Time wStartTime)

{
  underrun = false;

  sendCursor = 0;
  rcvCursor = 0;
  mOn = false;

  mRadio = wRadio;
  receiveOffset = wReceiveOffset;
  samplesPerSymbol = wRadioOversampling;
  mClock.set(wStartTime);
  powerScaling = 1.0;
  loadTest = false;
}

RadioInterface::~RadioInterface(void) {
  if (rcvBuffer!=NULL) delete rcvBuffer;
  //mReceiveFIFO.clear();
}

double RadioInterface::fullScaleInputValue(void) {
  return mRadio->fullScaleInputValue();
}

double RadioInterface::fullScaleOutputValue(void) {
  return mRadio->fullScaleOutputValue();
}

void RadioInterface::setPowerAttenuation(double dBAtten)
{
  float HWdBAtten = mRadio->setTxGain(-dBAtten);
  dBAtten -= (-HWdBAtten);
  float linearAtten = powf(10.0F,0.1F*dBAtten);
  if (linearAtten < 1.0)
    powerScaling = 1.0;
  else
    powerScaling = 1.0/sqrt(linearAtten);
  LOG(INFO) << "setting HW gain to " << HWdBAtten << " and power scaling to " << powerScaling;
}

short *RadioInterface::radioifyVector(signalVector &wVector, short *retVector, double scale, bool zeroOut)
{

  signalVector::iterator itr = wVector.begin();
  short *shortItr = retVector;
  if (zeroOut) {
    while (itr < wVector.end()) {
      *shortItr++ = 0;
      *shortItr++ = 0;
      itr++;
    }
  }
  else if (scale != 1.0) {
    while (itr < wVector.end()) {
      *shortItr++ = (short) (itr->real()*scale);
      *shortItr++ = (short) (itr->imag()*scale);
      itr++;
    }
  }
  else {
    while (itr < wVector.end()) {
      *shortItr++ = (short) (itr->real());
      *shortItr++ = (short) (itr->imag());
      itr++;
    }
  }

  return retVector;

}

void RadioInterface::unRadioifyVector(short *shortVector, signalVector& newVector)
{

  signalVector::iterator itr = newVector.begin();
  short *shortItr = shortVector;
  while (itr < newVector.end()) {
    *itr++ = Complex<float>(*shortItr,*(shortItr+1));
    //LOG(DEBUG) << (*(itr-1));
    shortItr += 2;
  }

}

bool started = false;

void RadioInterface::pushBuffer(void) {

  if (sendCursor < 2*INCHUNK*samplesPerSymbol) return;

  // send resampleVector
  int samplesWritten = mRadio->writeSamples(sendBuffer,
					  INCHUNK*samplesPerSymbol,
					  &underrun,
					  writeTimestamp);
  //LOG(DEBUG) << "writeTimestamp: " << writeTimestamp << ", samplesWritten: " << samplesWritten;

  writeTimestamp += (TIMESTAMP) samplesWritten;

  if (sendCursor > 2*samplesWritten)
    memcpy(sendBuffer,sendBuffer+samplesWritten*2,sizeof(short)*2*(sendCursor-2*samplesWritten));
  sendCursor = sendCursor - 2*samplesWritten;
}

void RadioInterface::pullBuffer(void)
{

  bool localUnderrun;

   // receive receiveVector
  short* shortVector = rcvBuffer+rcvCursor;
  //LOG(DEBUG) << "Reading USRP samples at timestamp " << readTimestamp;
  int samplesRead = mRadio->readSamples(shortVector,OUTCHUNK*samplesPerSymbol,&overrun,readTimestamp,&localUnderrun);
  underrun |= localUnderrun;
  readTimestamp += (TIMESTAMP) samplesRead;
  while (samplesRead < OUTCHUNK*samplesPerSymbol) {
    int oldSamplesRead = samplesRead;
    samplesRead += mRadio->readSamples(shortVector+2*samplesRead,
				     OUTCHUNK*samplesPerSymbol-samplesRead,
				     &overrun,
				     readTimestamp,
				     &localUnderrun);
    underrun |= localUnderrun;
    readTimestamp += (TIMESTAMP) (samplesRead - oldSamplesRead);
  }
  //LOG(DEBUG) << "samplesRead " << samplesRead;

  rcvCursor += samplesRead*2;

}

bool RadioInterface::tuneTx(double freq)
{
  return mRadio->setTxFreq(freq);
}

bool RadioInterface::tuneRx(double freq)
{
  return mRadio->setRxFreq(freq);
}

void RadioInterface::start()
{
  LOG(INFO) << "starting radio interface...";
  mAlignRadioServiceLoopThread.start((void * (*)(void*))AlignRadioServiceLoopAdapter,
                                     (void*)this);
  writeTimestamp = mRadio->initialWriteTimestamp();
  readTimestamp = mRadio->initialReadTimestamp();
  mRadio->start();
  LOG(DEBUG) << "Radio started";
  mRadio->updateAlignment(writeTimestamp-10000);
  mRadio->updateAlignment(writeTimestamp-10000);

  sendBuffer = new short[2*2*INCHUNK*samplesPerSymbol];
  rcvBuffer = new short[2*2*OUTCHUNK*samplesPerSymbol];

  mOn = true;

}

void *AlignRadioServiceLoopAdapter(RadioInterface *radioInterface)
{
  while (1) {
    radioInterface->alignRadio();
    pthread_testcancel();
  }
  return NULL;
}

void RadioInterface::alignRadio() {
  sleep(60);
  mRadio->updateAlignment(writeTimestamp+ (TIMESTAMP) 10000);
}

void RadioInterface::driveTransmitRadio(signalVector &radioBurst, bool zeroBurst) {

  if (!mOn) return;

  radioifyVector(radioBurst, sendBuffer+sendCursor, powerScaling, zeroBurst);

  sendCursor += (radioBurst.size()*2);

  pushBuffer();
}

void RadioInterface::driveReceiveRadio() {

  if (!mOn) return;

  if (mReceiveFIFO.size() > 8) return;

  pullBuffer();

  GSM::Time rcvClock = mClock.get();
  rcvClock.decTN(receiveOffset);
  unsigned tN = rcvClock.TN();
  int rcvSz = rcvCursor/2;
  int readSz = 0;
  const int symbolsPerSlot = gSlotLen + 8;

  // while there's enough data in receive buffer, form received
  //    GSM bursts and pass up to Transceiver
  // Using the 157-156-156-156 symbols per timeslot format.
  while (rcvSz > (symbolsPerSlot + (tN % 4 == 0))*samplesPerSymbol) {
    signalVector rxVector((symbolsPerSlot + (tN % 4 == 0))*samplesPerSymbol);
    unRadioifyVector(rcvBuffer+readSz*2,rxVector);
    GSM::Time tmpTime = rcvClock;
    if (rcvClock.FN() >= 0) {
      //LOG(DEBUG) << "FN: " << rcvClock.FN();
      radioVector *rxBurst = NULL;
      if (!loadTest)
        rxBurst = new radioVector(rxVector,tmpTime);
      else {
	if (tN % 4 == 0)
	  rxBurst = new radioVector(*finalVec9,tmpTime);
        else
          rxBurst = new radioVector(*finalVec,tmpTime);
      }
      mReceiveFIFO.put(rxBurst);
    }
    mClock.incTN();
    rcvClock.incTN();
    //if (mReceiveFIFO.size() >= 16) mReceiveFIFO.wait(8);
    //LOG(DEBUG) << "receiveFIFO: wrote radio vector at time: " << mClock.get() << ", new size: " << mReceiveFIFO.size() ;
    readSz += (symbolsPerSlot+(tN % 4 == 0))*samplesPerSymbol;
    rcvSz -= (symbolsPerSlot+(tN % 4 == 0))*samplesPerSymbol;

    tN = rcvClock.TN();
  }

  if (readSz > 0) {
    memcpy(rcvBuffer,rcvBuffer+2*readSz,sizeof(short)*2*(rcvCursor-readSz));
    rcvCursor = rcvCursor-2*readSz;
  }
}

<commit_msg>uhd: set attenuation relative to max RF gain<commit_after>/*
* Copyright 2008, 2009 Free Software Foundation, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Affero General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	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 Affero General Public License for more details.

	You should have received a copy of the GNU Affero General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

//#define NDEBUG
#include "radioInterface.h"
#include <Logger.h>

GSM::Time VectorQueue::nextTime() const
{
  GSM::Time retVal;
  ScopedLock lock(mLock);
  while (mQ.size()==0) mWriteSignal.wait(mLock);
  return mQ.top()->time();
}

radioVector* VectorQueue::getStaleBurst(const GSM::Time& targTime)
{
  ScopedLock lock(mLock);
  if ((mQ.size()==0)) {
    return NULL;
  }
  if (mQ.top()->time() < targTime) {
    radioVector* retVal = mQ.top();
    mQ.pop();
    return retVal;
  }
  return NULL;
}

radioVector* VectorQueue::getCurrentBurst(const GSM::Time& targTime)
{
  ScopedLock lock(mLock);
  if ((mQ.size()==0)) {
    return NULL;
  }
  if (mQ.top()->time() == targTime) {
    radioVector* retVal = mQ.top();
    mQ.pop();
    return retVal;
  }
  return NULL;
}

RadioInterface::RadioInterface(RadioDevice *wRadio,
                               int wReceiveOffset,
			       int wRadioOversampling,
			       int wTransceiverOversampling,
			       GSM::Time wStartTime)

{
  underrun = false;

  sendCursor = 0;
  rcvCursor = 0;
  mOn = false;

  mRadio = wRadio;
  receiveOffset = wReceiveOffset;
  samplesPerSymbol = wRadioOversampling;
  mClock.set(wStartTime);
  powerScaling = 1.0;
  loadTest = false;
}

RadioInterface::~RadioInterface(void) {
  if (rcvBuffer!=NULL) delete rcvBuffer;
  //mReceiveFIFO.clear();
}

double RadioInterface::fullScaleInputValue(void) {
  return mRadio->fullScaleInputValue();
}

double RadioInterface::fullScaleOutputValue(void) {
  return mRadio->fullScaleOutputValue();
}

void RadioInterface::setPowerAttenuation(double dBAtten)
{
  double HWatten = mRadio->setTxGain(mRadio->maxTxGain() - atten);
  atten -= (-HWatten);
  if (atten < 1.0)
    powerScaling = 1.0;
  else
    powerScaling = 1.0/sqrt(linearAtten);
  LOG(INFO) << "setting HW gain to " << HWdBAtten << " and power scaling to " << powerScaling;
}

short *RadioInterface::radioifyVector(signalVector &wVector, short *retVector, double scale, bool zeroOut)
{

  signalVector::iterator itr = wVector.begin();
  short *shortItr = retVector;
  if (zeroOut) {
    while (itr < wVector.end()) {
      *shortItr++ = 0;
      *shortItr++ = 0;
      itr++;
    }
  }
  else if (scale != 1.0) {
    while (itr < wVector.end()) {
      *shortItr++ = (short) (itr->real()*scale);
      *shortItr++ = (short) (itr->imag()*scale);
      itr++;
    }
  }
  else {
    while (itr < wVector.end()) {
      *shortItr++ = (short) (itr->real());
      *shortItr++ = (short) (itr->imag());
      itr++;
    }
  }

  return retVector;

}

void RadioInterface::unRadioifyVector(short *shortVector, signalVector& newVector)
{

  signalVector::iterator itr = newVector.begin();
  short *shortItr = shortVector;
  while (itr < newVector.end()) {
    *itr++ = Complex<float>(*shortItr,*(shortItr+1));
    //LOG(DEBUG) << (*(itr-1));
    shortItr += 2;
  }

}

bool started = false;

void RadioInterface::pushBuffer(void) {

  if (sendCursor < 2*INCHUNK*samplesPerSymbol) return;

  // send resampleVector
  int samplesWritten = mRadio->writeSamples(sendBuffer,
					  INCHUNK*samplesPerSymbol,
					  &underrun,
					  writeTimestamp);
  //LOG(DEBUG) << "writeTimestamp: " << writeTimestamp << ", samplesWritten: " << samplesWritten;

  writeTimestamp += (TIMESTAMP) samplesWritten;

  if (sendCursor > 2*samplesWritten)
    memcpy(sendBuffer,sendBuffer+samplesWritten*2,sizeof(short)*2*(sendCursor-2*samplesWritten));
  sendCursor = sendCursor - 2*samplesWritten;
}

void RadioInterface::pullBuffer(void)
{

  bool localUnderrun;

   // receive receiveVector
  short* shortVector = rcvBuffer+rcvCursor;
  //LOG(DEBUG) << "Reading USRP samples at timestamp " << readTimestamp;
  int samplesRead = mRadio->readSamples(shortVector,OUTCHUNK*samplesPerSymbol,&overrun,readTimestamp,&localUnderrun);
  underrun |= localUnderrun;
  readTimestamp += (TIMESTAMP) samplesRead;
  while (samplesRead < OUTCHUNK*samplesPerSymbol) {
    int oldSamplesRead = samplesRead;
    samplesRead += mRadio->readSamples(shortVector+2*samplesRead,
				     OUTCHUNK*samplesPerSymbol-samplesRead,
				     &overrun,
				     readTimestamp,
				     &localUnderrun);
    underrun |= localUnderrun;
    readTimestamp += (TIMESTAMP) (samplesRead - oldSamplesRead);
  }
  //LOG(DEBUG) << "samplesRead " << samplesRead;

  rcvCursor += samplesRead*2;

}

bool RadioInterface::tuneTx(double freq)
{
  return mRadio->setTxFreq(freq);
}

bool RadioInterface::tuneRx(double freq)
{
  return mRadio->setRxFreq(freq);
}

void RadioInterface::start()
{
  LOG(INFO) << "starting radio interface...";
  mAlignRadioServiceLoopThread.start((void * (*)(void*))AlignRadioServiceLoopAdapter,
                                     (void*)this);
  writeTimestamp = mRadio->initialWriteTimestamp();
  readTimestamp = mRadio->initialReadTimestamp();
  mRadio->start();
  LOG(DEBUG) << "Radio started";
  mRadio->updateAlignment(writeTimestamp-10000);
  mRadio->updateAlignment(writeTimestamp-10000);

  sendBuffer = new short[2*2*INCHUNK*samplesPerSymbol];
  rcvBuffer = new short[2*2*OUTCHUNK*samplesPerSymbol];

  mOn = true;

}

void *AlignRadioServiceLoopAdapter(RadioInterface *radioInterface)
{
  while (1) {
    radioInterface->alignRadio();
    pthread_testcancel();
  }
  return NULL;
}

void RadioInterface::alignRadio() {
  sleep(60);
  mRadio->updateAlignment(writeTimestamp+ (TIMESTAMP) 10000);
}

void RadioInterface::driveTransmitRadio(signalVector &radioBurst, bool zeroBurst) {

  if (!mOn) return;

  radioifyVector(radioBurst, sendBuffer+sendCursor, powerScaling, zeroBurst);

  sendCursor += (radioBurst.size()*2);

  pushBuffer();
}

void RadioInterface::driveReceiveRadio() {

  if (!mOn) return;

  if (mReceiveFIFO.size() > 8) return;

  pullBuffer();

  GSM::Time rcvClock = mClock.get();
  rcvClock.decTN(receiveOffset);
  unsigned tN = rcvClock.TN();
  int rcvSz = rcvCursor/2;
  int readSz = 0;
  const int symbolsPerSlot = gSlotLen + 8;

  // while there's enough data in receive buffer, form received
  //    GSM bursts and pass up to Transceiver
  // Using the 157-156-156-156 symbols per timeslot format.
  while (rcvSz > (symbolsPerSlot + (tN % 4 == 0))*samplesPerSymbol) {
    signalVector rxVector((symbolsPerSlot + (tN % 4 == 0))*samplesPerSymbol);
    unRadioifyVector(rcvBuffer+readSz*2,rxVector);
    GSM::Time tmpTime = rcvClock;
    if (rcvClock.FN() >= 0) {
      //LOG(DEBUG) << "FN: " << rcvClock.FN();
      radioVector *rxBurst = NULL;
      if (!loadTest)
        rxBurst = new radioVector(rxVector,tmpTime);
      else {
	if (tN % 4 == 0)
	  rxBurst = new radioVector(*finalVec9,tmpTime);
        else
          rxBurst = new radioVector(*finalVec,tmpTime);
      }
      mReceiveFIFO.put(rxBurst);
    }
    mClock.incTN();
    rcvClock.incTN();
    //if (mReceiveFIFO.size() >= 16) mReceiveFIFO.wait(8);
    //LOG(DEBUG) << "receiveFIFO: wrote radio vector at time: " << mClock.get() << ", new size: " << mReceiveFIFO.size() ;
    readSz += (symbolsPerSlot+(tN % 4 == 0))*samplesPerSymbol;
    rcvSz -= (symbolsPerSlot+(tN % 4 == 0))*samplesPerSymbol;

    tN = rcvClock.TN();
  }

  if (readSz > 0) {
    memcpy(rcvBuffer,rcvBuffer+2*readSz,sizeof(short)*2*(rcvCursor-readSz));
    rcvCursor = rcvCursor-2*readSz;
  }
}

<|endoftext|>


<commit_before>/** events.cc                                 -*- C++ -*-
    Rémi Attab, 18 Apr 2014
    Copyright (c) 2014 Datacratic.  All rights reserved.

    Publishable event implementation.

*/

#include "events.h"
#include "soa/service/zmq_endpoint.h"
#include "soa/service/zmq_named_pub_sub.h"

using namespace std;
using namespace ML;

namespace RTBKIT {

/******************************************************************************/
/* UTILS                                                                      */
/******************************************************************************/

namespace {

std::string publishTimestamp()
{
    return Date::now().print(5);
}

} // namespace anonymous

/******************************************************************************/
/* MATCHED WIN LOSS                                                           */
/******************************************************************************/

void
MatchedWinLoss::
initFinishedInfo(const FinishedInfo& info)
{
    auctionId = info.auctionId;
    impId = info.adSpotId;
    winPrice = info.winPrice;
    rawWinPrice = info.rawWinPrice;
    response = info.bid;
    requestStr = info.bidRequestStr;
    requestStrFormat = info.bidRequestStrFormat;
    request = info.bidRequest;
    meta = info.winMeta;
    augmentations = info.augmentations;
}

void
MatchedWinLoss::
initMisc(const PostAuctionEvent& event)
{
    uids = event.uids;
    timestamp = event.timestamp;
}

void
MatchedWinLoss::
initMisc(Date timestamp, UserIds uids)
{
    this->timestamp = timestamp;
    this->uids = std::move(uids);
}

MatchedWinLoss::
MatchedWinLoss(
        Type type,
        Confidence confidence,
        const PostAuctionEvent& event,
        const FinishedInfo& info) :
    type(type), confidence(confidence)
{
    initFinishedInfo(info);
    initMisc(event);
}

MatchedWinLoss::
    MatchedWinLoss(
            Type type,
            Confidence confidence,
            const FinishedInfo& info,
            Date timestamp,
            UserIds uids) :
    type(type), confidence(confidence)
{
    initFinishedInfo(info);
    initMisc(timestamp, std::move(uids));
}

std::string
MatchedWinLoss::
typeString() const
{
    switch (type) {
    case LateWin:
    case Win: return "WIN";
    case Loss: return "LOSS";
    }
    ExcAssert(false);
}

std::string
MatchedWinLoss::
confidenceString() const
{
    switch (confidence) {
    case Inferred: return "inferred";
    case Guaranteed: return "guaranteed";
    }

    ExcAssert(false);
}

size_t
MatchedWinLoss::
impIndex() const
{
    return request->findAdSpotIndex(impId);
}

void
MatchedWinLoss::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "MATCHED" + typeString(),                // 0
            publishTimestamp(),                      // 1

            auctionId.toString(),                    // 2
            std::to_string(impIndex()),              // 3
            response.agent,                          // 4
            response.account.at(1, ""),              // 5

            winPrice.toString(),                     // 6
            response.price.maxPrice.toString(),      // 7
            std::to_string(response.price.priority), // 8

            requestStr,                              // 9
            response.bidData,                        // 10
            response.meta,                           // 11

            // This is where things start to get weird.

            std::to_string(response.creativeId),     // 12
            response.creativeName,                   // 13
            response.account.at(0, ""),              // 14

            uids.toJsonStr(),                        // 15
            meta,                                    // 16

            // And this is where we lose all pretenses of sanity.

            response.account.at(0, ""),              // 17
            impId.toString(),                        // 18
            response.account.toString(),             // 19

            // Ok back to sanity now.

            requestStrFormat,                        // 20
            rawWinPrice.toString()                   // 21
        );
}

/******************************************************************************/
/* MATCHED CAMPAIGN EVENT                                                     */
/******************************************************************************/

MatchedCampaignEvent::
MatchedCampaignEvent(std::string label, const FinishedInfo& info) :
    label(std::move(label)),
    auctionId(info.auctionId),
    impId(info.adSpotId),
    account(info.bid.account),
    requestStr(info.bidRequestStr),
    request(info.bidRequest),
    requestStrFormat(info.bidRequestStrFormat),
    bid(info.bidToJson()),
    win(info.winToJson()),
    campaignEvents(info.campaignEvents.toJson()),
    visits(info.visitsToJson()),
    augmentations(info.augmentations)
{
    auto it = std::find_if(info.campaignEvents.begin(), info.campaignEvents.end(),
                    [&](const CampaignEvent& event) {
                        return event.label_ == label;
                    }
                );

    if(it != info.campaignEvents.end())
        timestamp = it->time_;
}
size_t
MatchedCampaignEvent::
impIndex() const
{
    return request->findAdSpotIndex(impId);
}

void
MatchedCampaignEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "MATCHED" + label,    // 0
            publishTimestamp(),   // 1

            auctionId.toString(), // 2
            impId.toString(),     // 3
            requestStr,           // 4

            bid,                  // 5
            win,                  // 6
            campaignEvents,       // 7
            visits,               // 8

            account.at(0, ""),    // 9
            account.at(1, ""),    // 10
            account.toString(),   // 11

            requestStrFormat      // 12
    );
}

/******************************************************************************/
/* UNMATCHED EVENT                                                            */
/******************************************************************************/

UnmatchedEvent::
UnmatchedEvent(std::string reason, PostAuctionEvent event) :
    reason(std::move(reason)),
    event(std::move(event))
{}

void
UnmatchedEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "UNMATCHED" + event.label,                           // 0
            publishTimestamp(),                                  // 1

            reason,                                              // 2
            event.auctionId.toString(),                          // 3
            event.adSpotId.toString(),                           // 4

            std::to_string(event.timestamp.secondsSinceEpoch()), // 5
            event.metadata.toJson()                              // 6
        );
}

/******************************************************************************/
/* POST AUCTION ERROR EVENT                                                   */
/******************************************************************************/

PostAuctionErrorEvent::
PostAuctionErrorEvent(std::string key, std::string message) :
    key(std::move(key)), message(std::move(message))
{}

void
PostAuctionErrorEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish("PAERROR", publishTimestamp(), key, message);
}

} // namepsace RTBKIT
<commit_msg>Update events.cc in order to log augmentation data<commit_after>/** events.cc                                 -*- C++ -*-
    Rémi Attab, 18 Apr 2014
    Copyright (c) 2014 Datacratic.  All rights reserved.

    Publishable event implementation.

*/

#include "events.h"
#include "soa/service/zmq_endpoint.h"
#include "soa/service/zmq_named_pub_sub.h"

using namespace std;
using namespace ML;

namespace RTBKIT {

/******************************************************************************/
/* UTILS                                                                      */
/******************************************************************************/

namespace {

std::string publishTimestamp()
{
    return Date::now().print(5);
}

} // namespace anonymous

/******************************************************************************/
/* MATCHED WIN LOSS                                                           */
/******************************************************************************/

void
MatchedWinLoss::
initFinishedInfo(const FinishedInfo& info)
{
    auctionId = info.auctionId;
    impId = info.adSpotId;
    winPrice = info.winPrice;
    rawWinPrice = info.rawWinPrice;
    response = info.bid;
    requestStr = info.bidRequestStr;
    requestStrFormat = info.bidRequestStrFormat;
    request = info.bidRequest;
    meta = info.winMeta;
    augmentations = info.augmentations;
}

void
MatchedWinLoss::
initMisc(const PostAuctionEvent& event)
{
    uids = event.uids;
    timestamp = event.timestamp;
}

void
MatchedWinLoss::
initMisc(Date timestamp, UserIds uids)
{
    this->timestamp = timestamp;
    this->uids = std::move(uids);
}

MatchedWinLoss::
MatchedWinLoss(
        Type type,
        Confidence confidence,
        const PostAuctionEvent& event,
        const FinishedInfo& info) :
    type(type), confidence(confidence)
{
    initFinishedInfo(info);
    initMisc(event);
}

MatchedWinLoss::
    MatchedWinLoss(
            Type type,
            Confidence confidence,
            const FinishedInfo& info,
            Date timestamp,
            UserIds uids) :
    type(type), confidence(confidence)
{
    initFinishedInfo(info);
    initMisc(timestamp, std::move(uids));
}

std::string
MatchedWinLoss::
typeString() const
{
    switch (type) {
    case LateWin:
    case Win: return "WIN";
    case Loss: return "LOSS";
    }
    ExcAssert(false);
}

std::string
MatchedWinLoss::
confidenceString() const
{
    switch (confidence) {
    case Inferred: return "inferred";
    case Guaranteed: return "guaranteed";
    }

    ExcAssert(false);
}

size_t
MatchedWinLoss::
impIndex() const
{
    return request->findAdSpotIndex(impId);
}

void
MatchedWinLoss::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "MATCHED" + typeString(),                // 0
            publishTimestamp(),                      // 1

            auctionId.toString(),                    // 2
            std::to_string(impIndex()),              // 3
            response.agent,                          // 4
            response.account.at(1, ""),              // 5

            winPrice.toString(),                     // 6
            response.price.maxPrice.toString(),      // 7
            std::to_string(response.price.priority), // 8

            requestStr,                              // 9
            response.bidData,                        // 10
            response.meta,                           // 11

            // This is where things start to get weird.

            std::to_string(response.creativeId),     // 12
            response.creativeName,                   // 13
            response.account.at(0, ""),              // 14

            uids.toJsonStr(),                        // 15
            meta,                                    // 16

            // And this is where we lose all pretenses of sanity.

            response.account.at(0, ""),              // 17
            impId.toString(),                        // 18
            response.account.toString(),             // 19

            // Ok back to sanity now.

            requestStrFormat,                        // 20
            rawWinPrice.toString(),                  // 21
            augmentations.toString()
        );
}

/******************************************************************************/
/* MATCHED CAMPAIGN EVENT                                                     */
/******************************************************************************/

MatchedCampaignEvent::
MatchedCampaignEvent(std::string label, const FinishedInfo& info) :
    label(std::move(label)),
    auctionId(info.auctionId),
    impId(info.adSpotId),
    account(info.bid.account),
    requestStr(info.bidRequestStr),
    request(info.bidRequest),
    requestStrFormat(info.bidRequestStrFormat),
    bid(info.bidToJson()),
    win(info.winToJson()),
    campaignEvents(info.campaignEvents.toJson()),
    visits(info.visitsToJson()),
    augmentations(info.augmentations)
{
    auto it = std::find_if(info.campaignEvents.begin(), info.campaignEvents.end(),
                    [&](const CampaignEvent& event) {
                        return event.label_ == label;
                    }
                );

    if(it != info.campaignEvents.end())
        timestamp = it->time_;
}
size_t
MatchedCampaignEvent::
impIndex() const
{
    return request->findAdSpotIndex(impId);
}

void
MatchedCampaignEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "MATCHED" + label,    // 0
            publishTimestamp(),   // 1

            auctionId.toString(), // 2
            impId.toString(),     // 3
            requestStr,           // 4

            bid,                  // 5
            win,                  // 6
            campaignEvents,       // 7
            visits,               // 8

            account.at(0, ""),    // 9
            account.at(1, ""),    // 10
            account.toString(),   // 11

            requestStrFormat      // 12
    );
}

/******************************************************************************/
/* UNMATCHED EVENT                                                            */
/******************************************************************************/

UnmatchedEvent::
UnmatchedEvent(std::string reason, PostAuctionEvent event) :
    reason(std::move(reason)),
    event(std::move(event))
{}

void
UnmatchedEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "UNMATCHED" + event.label,                           // 0
            publishTimestamp(),                                  // 1

            reason,                                              // 2
            event.auctionId.toString(),                          // 3
            event.adSpotId.toString(),                           // 4

            std::to_string(event.timestamp.secondsSinceEpoch()), // 5
            event.metadata.toJson()                              // 6
        );
}

/******************************************************************************/
/* POST AUCTION ERROR EVENT                                                   */
/******************************************************************************/

PostAuctionErrorEvent::
PostAuctionErrorEvent(std::string key, std::string message) :
    key(std::move(key)), message(std::move(message))
{}

void
PostAuctionErrorEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish("PAERROR", publishTimestamp(), key, message);
}

} // namepsace RTBKIT
<|endoftext|>


<commit_before>/** events.cc                                 -*- C++ -*-
    Rémi Attab, 18 Apr 2014
    Copyright (c) 2014 Datacratic.  All rights reserved.

    Publishable event implementation.

*/

#include "events.h"
#include "soa/service/zmq_endpoint.h"
#include "soa/service/zmq_named_pub_sub.h"

using namespace std;
using namespace ML;

namespace RTBKIT {

/******************************************************************************/
/* UTILS                                                                      */
/******************************************************************************/

namespace {

std::string publishTimestamp()
{
    return Date::now().print(5);
}

} // namespace anonymous

/******************************************************************************/
/* MATCHED WIN LOSS                                                           */
/******************************************************************************/

void
MatchedWinLoss::
initFinishedInfo(const FinishedInfo& info)
{
    auctionId = info.auctionId;
    impId = info.adSpotId;
    winPrice = info.winPrice;
    rawWinPrice = info.rawWinPrice;
    response = info.bid;
    requestStr = info.bidRequestStr;
    requestStrFormat = info.bidRequestStrFormat;
    request = info.bidRequest;
    meta = info.winMeta;
    augmentations = info.augmentations;
}

void
MatchedWinLoss::
initMisc(const PostAuctionEvent& event)
{
    uids = event.uids;
    timestamp = event.timestamp;
}

void
MatchedWinLoss::
initMisc(Date timestamp, UserIds uids)
{
    this->timestamp = timestamp;
    this->uids = std::move(uids);
}

MatchedWinLoss::
MatchedWinLoss(
        Type type,
        Confidence confidence,
        const PostAuctionEvent& event,
        const FinishedInfo& info) :
    type(type), confidence(confidence)
{
    initFinishedInfo(info);
    initMisc(event);
}

MatchedWinLoss::
    MatchedWinLoss(
            Type type,
            Confidence confidence,
            const FinishedInfo& info,
            Date timestamp,
            UserIds uids) :
    type(type), confidence(confidence)
{
    initFinishedInfo(info);
    initMisc(timestamp, std::move(uids));
}

std::string
MatchedWinLoss::
typeString() const
{
    switch (type) {
    case LateWin:
    case Win: return "WIN";
    case Loss: return "LOSS";
    }
    ExcAssert(false);
}

std::string
MatchedWinLoss::
confidenceString() const
{
    switch (confidence) {
    case Inferred: return "inferred";
    case Guaranteed: return "guaranteed";
    }

    ExcAssert(false);
}

size_t
MatchedWinLoss::
impIndex() const
{
    return request->findAdSpotIndex(impId);
}

void
MatchedWinLoss::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "MATCHED" + typeString(),
            publishTimestamp(),

            auctionId.toString(),
            std::to_string(impIndex()),
            request->findAdSpotIndex(impId),
            response.agent,
            response.account.at(1, ""),

            winPrice.toString(),
            response.price.maxPrice.toString(),
            std::to_string(response.price.priority),

            requestStr,
            response.bidData,
            response.meta,

            // This is where things start to get weird.

            std::to_string(response.creativeId),
            response.creativeName,
            response.account.at(0, ""),

            uids.toJsonStr(),
            meta,

            // And this is where we lose all pretenses of sanity.

            response.account.at(0, ""),
            impId.toString(),
            response.account.toString(),

            // Ok back to sanity now.

            requestStrFormat,
            rawWinPrice.toString()
        );
}

void
MatchedWinLoss::
sendAgentMessage(ZmqNamedClientBus& agents) const
{
    std::string channel =
        type == LateWin ? "LATEWIN" : typeString();

    agents.sendMessage(
            response.agent,
            channel,
            timestamp,
            confidenceString(),

            auctionId.toString(),
            std::to_string(impIndex()),
            winPrice.toString(),

            requestStrFormat,
            requestStr,
            response.bidData,
            response.meta,
            augmentations.toJson()
        );
}

/******************************************************************************/
/* MATCHED CAMPAIGN EVENT                                                     */
/******************************************************************************/

MatchedCampaignEvent::
MatchedCampaignEvent(std::string label, const FinishedInfo& info) :
    label(std::move(label)),
    auctionId(info.auctionId),
    impId(info.adSpotId),
    account(info.bid.account),
    requestStr(info.bidRequestStr),
    request(info.bidRequest),
    requestStrFormat(info.bidRequestStrFormat),
    bid(info.bidToJson()),
    win(info.winToJson()),
    campaignEvents(info.campaignEvents.toJson()),
    visits(info.visitsToJson()),
    augmentations(info.augmentations)
{}

size_t
MatchedCampaignEvent::
impIndex() const
{
    return request->findAdSpotIndex(impId);
}

void
MatchedCampaignEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "MATCHED" + label,
            publishTimestamp(),

            auctionId.toString(),
            impId.toString(),
            requestStr,

            bid,
            win,
            campaignEvents,
            visits,

            account.at(0, ""),
            account.at(1, ""),
            account.toString(),

            requestStrFormat
    );
}

void
MatchedCampaignEvent::
sendAgentMessage(const std::string& agent, ZmqNamedClientBus& endpoint) const
{
    endpoint.sendMessage(
            agent,
            "CAMPAIGN_EVENT",
            label,
            Date::now(),

            auctionId.toString(),
            impId.toString(),
            std::to_string(impIndex()),

            requestStrFormat,
            requestStr,
            augmentations.toJson(),

            bid,
            win,
            campaignEvents,
            visits
        );
}

/******************************************************************************/
/* UNMATCHED EVENT                                                            */
/******************************************************************************/

UnmatchedEvent::
UnmatchedEvent(std::string reason, PostAuctionEvent event) :
    reason(std::move(reason)),
    event(std::move(event))
{}

void
UnmatchedEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "UNMATCHED" + event.label,
            publishTimestamp(),

            reason,
            event.auctionId.toString(),
            event.adSpotId.toString(),

            std::to_string(event.timestamp.secondsSinceEpoch()),
            event.metadata.toJson()
        );
}

/******************************************************************************/
/* POST AUCTION ERROR EVENT                                                   */
/******************************************************************************/

PostAuctionErrorEvent::
PostAuctionErrorEvent(std::string key, std::string message) :
    key(std::move(key)), message(std::move(message))
{}

void
PostAuctionErrorEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish("PAERROR", publishTimestamp(), key, message);
}

} // namepsace RTBKIT
<commit_msg>Fixed a slight mix up in the MATCHWIN events.<commit_after>/** events.cc                                 -*- C++ -*-
    Rémi Attab, 18 Apr 2014
    Copyright (c) 2014 Datacratic.  All rights reserved.

    Publishable event implementation.

*/

#include "events.h"
#include "soa/service/zmq_endpoint.h"
#include "soa/service/zmq_named_pub_sub.h"

using namespace std;
using namespace ML;

namespace RTBKIT {

/******************************************************************************/
/* UTILS                                                                      */
/******************************************************************************/

namespace {

std::string publishTimestamp()
{
    return Date::now().print(5);
}

} // namespace anonymous

/******************************************************************************/
/* MATCHED WIN LOSS                                                           */
/******************************************************************************/

void
MatchedWinLoss::
initFinishedInfo(const FinishedInfo& info)
{
    auctionId = info.auctionId;
    impId = info.adSpotId;
    winPrice = info.winPrice;
    rawWinPrice = info.rawWinPrice;
    response = info.bid;
    requestStr = info.bidRequestStr;
    requestStrFormat = info.bidRequestStrFormat;
    request = info.bidRequest;
    meta = info.winMeta;
    augmentations = info.augmentations;
}

void
MatchedWinLoss::
initMisc(const PostAuctionEvent& event)
{
    uids = event.uids;
    timestamp = event.timestamp;
}

void
MatchedWinLoss::
initMisc(Date timestamp, UserIds uids)
{
    this->timestamp = timestamp;
    this->uids = std::move(uids);
}

MatchedWinLoss::
MatchedWinLoss(
        Type type,
        Confidence confidence,
        const PostAuctionEvent& event,
        const FinishedInfo& info) :
    type(type), confidence(confidence)
{
    initFinishedInfo(info);
    initMisc(event);
}

MatchedWinLoss::
    MatchedWinLoss(
            Type type,
            Confidence confidence,
            const FinishedInfo& info,
            Date timestamp,
            UserIds uids) :
    type(type), confidence(confidence)
{
    initFinishedInfo(info);
    initMisc(timestamp, std::move(uids));
}

std::string
MatchedWinLoss::
typeString() const
{
    switch (type) {
    case LateWin:
    case Win: return "WIN";
    case Loss: return "LOSS";
    }
    ExcAssert(false);
}

std::string
MatchedWinLoss::
confidenceString() const
{
    switch (confidence) {
    case Inferred: return "inferred";
    case Guaranteed: return "guaranteed";
    }

    ExcAssert(false);
}

size_t
MatchedWinLoss::
impIndex() const
{
    return request->findAdSpotIndex(impId);
}

void
MatchedWinLoss::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "MATCHED" + typeString(),            // 0
            publishTimestamp(),

            auctionId.toString(),                // 2
            std::to_string(impIndex()),
            response.agent,
            response.account.at(1, ""),

            winPrice.toString(),                 // 6
            response.price.maxPrice.toString(),
            std::to_string(response.price.priority),

            requestStr,                          // 9
            response.bidData,
            response.meta,

            // This is where things start to get weird.

            std::to_string(response.creativeId), // 12
            response.creativeName,
            response.account.at(0, ""),

            uids.toJsonStr(),                    // 15
            meta,

            // And this is where we lose all pretenses of sanity.

            response.account.at(0, ""),          // 17
            impId.toString(),
            response.account.toString(),

            // Ok back to sanity now.

            requestStrFormat,                    // 20
            rawWinPrice.toString()
        );
}

void
MatchedWinLoss::
sendAgentMessage(ZmqNamedClientBus& agents) const
{
    std::string channel =
        type == LateWin ? "LATEWIN" : typeString();

    agents.sendMessage(
            response.agent,
            channel,
            timestamp,
            confidenceString(),

            auctionId.toString(),
            std::to_string(impIndex()),
            winPrice.toString(),

            requestStrFormat,
            requestStr,
            response.bidData,
            response.meta,
            augmentations.toJson()
        );
}

/******************************************************************************/
/* MATCHED CAMPAIGN EVENT                                                     */
/******************************************************************************/

MatchedCampaignEvent::
MatchedCampaignEvent(std::string label, const FinishedInfo& info) :
    label(std::move(label)),
    auctionId(info.auctionId),
    impId(info.adSpotId),
    account(info.bid.account),
    requestStr(info.bidRequestStr),
    request(info.bidRequest),
    requestStrFormat(info.bidRequestStrFormat),
    bid(info.bidToJson()),
    win(info.winToJson()),
    campaignEvents(info.campaignEvents.toJson()),
    visits(info.visitsToJson()),
    augmentations(info.augmentations)
{}

size_t
MatchedCampaignEvent::
impIndex() const
{
    return request->findAdSpotIndex(impId);
}

void
MatchedCampaignEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "MATCHED" + label,
            publishTimestamp(),

            auctionId.toString(),
            impId.toString(),
            requestStr,

            bid,
            win,
            campaignEvents,
            visits,

            account.at(0, ""),
            account.at(1, ""),
            account.toString(),

            requestStrFormat
    );
}

void
MatchedCampaignEvent::
sendAgentMessage(const std::string& agent, ZmqNamedClientBus& endpoint) const
{
    endpoint.sendMessage(
            agent,
            "CAMPAIGN_EVENT",
            label,
            Date::now(),

            auctionId.toString(),
            impId.toString(),
            std::to_string(impIndex()),

            requestStrFormat,
            requestStr,
            augmentations.toJson(),

            bid,
            win,
            campaignEvents,
            visits
        );
}

/******************************************************************************/
/* UNMATCHED EVENT                                                            */
/******************************************************************************/

UnmatchedEvent::
UnmatchedEvent(std::string reason, PostAuctionEvent event) :
    reason(std::move(reason)),
    event(std::move(event))
{}

void
UnmatchedEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish(
            "UNMATCHED" + event.label,
            publishTimestamp(),

            reason,
            event.auctionId.toString(),
            event.adSpotId.toString(),

            std::to_string(event.timestamp.secondsSinceEpoch()),
            event.metadata.toJson()
        );
}

/******************************************************************************/
/* POST AUCTION ERROR EVENT                                                   */
/******************************************************************************/

PostAuctionErrorEvent::
PostAuctionErrorEvent(std::string key, std::string message) :
    key(std::move(key)), message(std::move(message))
{}

void
PostAuctionErrorEvent::
publish(ZmqNamedPublisher& logger) const
{
    logger.publish("PAERROR", publishTimestamp(), key, message);
}

} // namepsace RTBKIT
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: QueryTabWinUndoAct.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 16:26:17 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef DBAUI_OQueryTabWinUndoAct_HXX
#include "QueryTabWinUndoAct.hxx"
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef DBAUI_QUERY_TABLEWINDOW_HXX
#include "QTableWindow.hxx"
#endif
#ifndef DBAUI_QUERY_TABLEWINDOWDATA_HXX
#include "QTableWindowData.hxx"
#endif
#ifndef DBAUI_TABLECONNECTION_HXX
#include "TableConnection.hxx"
#endif
#ifndef DBAUI_TABLECONNECTIONDATA_HXX
#include "TableConnectionData.hxx"
#endif
#ifndef DBAUI_QUERYDESIGNFIELDUNDOACT_HXX
#include "QueryDesignFieldUndoAct.hxx"
#endif
#ifndef DBAUI_QUERYTABLEVIEW_HXX
#include "QueryTableView.hxx"
#endif

using namespace dbaui;
DBG_NAME(OQueryDesignFieldUndoAct)
OQueryDesignFieldUndoAct::OQueryDesignFieldUndoAct(OSelectionBrowseBox* pSelBrwBox, USHORT nCommentID)
    : OCommentUndoAction(nCommentID)
    , pOwner(pSelBrwBox)
    , m_nColumnPostion(BROWSER_INVALIDID)
{
    DBG_CTOR(OQueryDesignFieldUndoAct,NULL);
}
// -----------------------------------------------------------------------------
OQueryDesignFieldUndoAct::~OQueryDesignFieldUndoAct()
{
    DBG_DTOR(OQueryDesignFieldUndoAct,NULL);
    pOwner = NULL;
}
// -----------------------------------------------------------------------------

DBG_NAME(OQueryTabWinUndoAct )
// ------------------------------------------------------------------------------------------------
OQueryTabWinUndoAct::OQueryTabWinUndoAct(OQueryTableView* pOwner, USHORT nCommentID)
    :OQueryDesignUndoAction(pOwner, nCommentID)
    ,m_pTabWin(NULL)
{
    DBG_CTOR(OQueryTabWinUndoAct ,NULL);
}
//==============================================================================
OQueryTabWinUndoAct::~OQueryTabWinUndoAct()
{
    DBG_DTOR(OQueryTabWinUndoAct ,NULL);
    if (m_bOwnerOfObjects)
    {   // wenn ich der alleinige Owner des Fenster bin, muss ich dafuer sorgen, dass es geloescht wird
        OSL_ENSURE(m_pTabWin != NULL, "OQueryTabWinUndoAct::~OQueryTabWinUndoAct() : m_pTabWin sollte nicht NULL sein");
        OSL_ENSURE(!m_pTabWin->IsVisible(), "OQueryTabWinUndoAct::~OQueryTabWinUndoAct() : *m_pTabWin sollte nicht sichtbar sein");

        delete m_pTabWin->GetData();
        if ( m_pTabWin )
            m_pTabWin->clearListBox();
        delete m_pTabWin;

        // und natuerlich auch die entsprechenden Connections
        ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
        for(;aIter != m_vTableConnection.end();++aIter)
        {
            m_pOwner->DeselectConn(*aIter);
            delete (*aIter)->GetData();
            delete (*aIter);
        }
        m_vTableConnection.clear();
    }
}
//------------------------------------------------------------------------------
void OTabFieldCellModifiedUndoAct::Undo()
{
    OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
    OSL_ENSURE(m_nColumnPostion < pOwner->GetColumnCount(),"Position outside the column count!");
    if ( m_nColumnPostion != BROWSER_INVALIDID )
    {
        USHORT nColumnId = pOwner->GetColumnId(m_nColumnPostion);
        String strNext = pOwner->GetCellContents(m_nCellIndex, nColumnId);
        pOwner->SetCellContents(m_nCellIndex, nColumnId, m_strNextCellContents);
        m_strNextCellContents = strNext;
    }
}

//------------------------------------------------------------------------------
void OTabFieldSizedUndoAct::Undo()
{
    OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
    if ( m_nColumnPostion != BROWSER_INVALIDID )
    {
        USHORT nColumnId = pOwner->GetColumnId(m_nColumnPostion);
        long nNextWidth = pOwner->GetColumnWidth(nColumnId);
        pOwner->SetColWidth(nColumnId, m_nNextWidth);
        m_nNextWidth = nNextWidth;
    }
}
// -----------------------------------------------------------------------------
void OTabFieldMovedUndoAct::Undo()
{
    OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
    if ( m_nColumnPostion != BROWSER_INVALIDID )
    {
        sal_uInt16 nId = pDescr->GetColumnId();
        USHORT nOldPos = pOwner->GetColumnPos(nId);
        pOwner->SetColumnPos(nId,m_nColumnPostion);
        pOwner->ColumnMoved(nId,FALSE);
        m_nColumnPostion = nOldPos;
    }
}
// -----------------------------------------------------------------------------

<commit_msg>INTEGRATION: CWS dba201b (1.8.146); FILE MERGED 2005/09/21 10:11:49 oj 1.8.146.2: RESYNC: (1.8-1.9); FILE MERGED 2005/07/06 10:36:26 oj 1.8.146.1: #123168# check if we are in undo mode<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: QueryTabWinUndoAct.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2005-09-23 12:43:27 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef DBAUI_OQueryTabWinUndoAct_HXX
#include "QueryTabWinUndoAct.hxx"
#endif
#ifndef _OSL_DIAGNOSE_H_
#include <osl/diagnose.h>
#endif
#ifndef DBAUI_QUERY_TABLEWINDOW_HXX
#include "QTableWindow.hxx"
#endif
#ifndef DBAUI_QUERY_TABLEWINDOWDATA_HXX
#include "QTableWindowData.hxx"
#endif
#ifndef DBAUI_TABLECONNECTION_HXX
#include "TableConnection.hxx"
#endif
#ifndef DBAUI_TABLECONNECTIONDATA_HXX
#include "TableConnectionData.hxx"
#endif
#ifndef DBAUI_QUERYDESIGNFIELDUNDOACT_HXX
#include "QueryDesignFieldUndoAct.hxx"
#endif
#ifndef DBAUI_QUERYTABLEVIEW_HXX
#include "QueryTableView.hxx"
#endif

using namespace dbaui;
DBG_NAME(OQueryDesignFieldUndoAct)
OQueryDesignFieldUndoAct::OQueryDesignFieldUndoAct(OSelectionBrowseBox* pSelBrwBox, USHORT nCommentID)
    : OCommentUndoAction(nCommentID)
    , pOwner(pSelBrwBox)
    , m_nColumnPostion(BROWSER_INVALIDID)
{
    DBG_CTOR(OQueryDesignFieldUndoAct,NULL);
}
// -----------------------------------------------------------------------------
OQueryDesignFieldUndoAct::~OQueryDesignFieldUndoAct()
{
    DBG_DTOR(OQueryDesignFieldUndoAct,NULL);
    pOwner = NULL;
}
// -----------------------------------------------------------------------------

DBG_NAME(OQueryTabWinUndoAct )
// ------------------------------------------------------------------------------------------------
OQueryTabWinUndoAct::OQueryTabWinUndoAct(OQueryTableView* pOwner, USHORT nCommentID)
    :OQueryDesignUndoAction(pOwner, nCommentID)
    ,m_pTabWin(NULL)
{
    DBG_CTOR(OQueryTabWinUndoAct ,NULL);
}
//==============================================================================
OQueryTabWinUndoAct::~OQueryTabWinUndoAct()
{
    DBG_DTOR(OQueryTabWinUndoAct ,NULL);
    if (m_bOwnerOfObjects)
    {   // wenn ich der alleinige Owner des Fenster bin, muss ich dafuer sorgen, dass es geloescht wird
        OSL_ENSURE(m_pTabWin != NULL, "OQueryTabWinUndoAct::~OQueryTabWinUndoAct() : m_pTabWin sollte nicht NULL sein");
        OSL_ENSURE(!m_pTabWin->IsVisible(), "OQueryTabWinUndoAct::~OQueryTabWinUndoAct() : *m_pTabWin sollte nicht sichtbar sein");

        delete m_pTabWin->GetData();
        if ( m_pTabWin )
            m_pTabWin->clearListBox();
        delete m_pTabWin;

        // und natuerlich auch die entsprechenden Connections
        ::std::vector<OTableConnection*>::iterator aIter = m_vTableConnection.begin();
        for(;aIter != m_vTableConnection.end();++aIter)
        {
            m_pOwner->DeselectConn(*aIter);
            delete (*aIter)->GetData();
            delete (*aIter);
        }
        m_vTableConnection.clear();
    }
}
//------------------------------------------------------------------------------
void OTabFieldCellModifiedUndoAct::Undo()
{
    pOwner->EnterUndoMode();
    OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
    OSL_ENSURE(m_nColumnPostion < pOwner->GetColumnCount(),"Position outside the column count!");
    if ( m_nColumnPostion != BROWSER_INVALIDID )
    {
        USHORT nColumnId = pOwner->GetColumnId(m_nColumnPostion);
        String strNext = pOwner->GetCellContents(m_nCellIndex, nColumnId);
        pOwner->SetCellContents(m_nCellIndex, nColumnId, m_strNextCellContents);
        m_strNextCellContents = strNext;
    }
    pOwner->LeaveUndoMode();
}

//------------------------------------------------------------------------------
void OTabFieldSizedUndoAct::Undo()
{
    pOwner->EnterUndoMode();
    OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
    if ( m_nColumnPostion != BROWSER_INVALIDID )
    {
        USHORT nColumnId = pOwner->GetColumnId(m_nColumnPostion);
        long nNextWidth = pOwner->GetColumnWidth(nColumnId);
        pOwner->SetColWidth(nColumnId, m_nNextWidth);
        m_nNextWidth = nNextWidth;
    }
    pOwner->LeaveUndoMode();
}
// -----------------------------------------------------------------------------
void OTabFieldMovedUndoAct::Undo()
{
    pOwner->EnterUndoMode();
    OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
    if ( m_nColumnPostion != BROWSER_INVALIDID )
    {
        sal_uInt16 nId = pDescr->GetColumnId();
        USHORT nOldPos = pOwner->GetColumnPos(nId);
        pOwner->SetColumnPos(nId,m_nColumnPostion);
        pOwner->ColumnMoved(nId,FALSE);
        m_nColumnPostion = nOldPos;
    }
    pOwner->LeaveUndoMode();
}
// -----------------------------------------------------------------------------

<|endoftext|>


<commit_before>/**
 * @brief Implementation of bridge.
 *
 * These utilities allow us to manage Postgres metadata.
 *
 * Copyright(c) 2015, CMU
 */

#include <iostream>
#include <assert.h>
#include <sys/types.h>
#include <unistd.h>

#include "backend/bridge/ddl/bridge.h"
#include "backend/common/logger.h"

#include "postgres.h"
#include "c.h"
#include "miscadmin.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/indexing.h"
#include "catalog/pg_attribute.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_class.h"
#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_type.h"
#include "common/fe_memutils.h"
#include "utils/rel.h"
#include "utils/ruleutils.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
#include "parser/parse_type.h"

namespace peloton {
namespace bridge {

//===--------------------------------------------------------------------===//
// Getters
//===--------------------------------------------------------------------===//

/**
 * @brief Get the pg class tuple
 * @param tuple relevant tuple if it exists, NULL otherwise
 */
HeapTuple Bridge::GetPGClassTupleForRelationOid(Oid relation_id) {
  Relation pg_class_rel;
  HeapTuple tuple = NULL;

  PelotonStartTransactionCommand();

  // Open pg_class table
  pg_class_rel = heap_open(RelationRelationId, AccessShareLock);

  // Search the pg_class table with given relation id
  tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relation_id));
  if (!HeapTupleIsValid(tuple)) {
    elog(DEBUG2, "cache lookup failed for relation %u", relation_id);
    // Don't break here, we need to close heap and commit.
  }

  heap_close(pg_class_rel, AccessShareLock);

  PelotonCommitTransactionCommand();

  return tuple;
}

/**
 * @brief Get the pg class tuple
 * @param tuple relevant tuple if it exists, NULL otherwise
 */
HeapTuple Bridge::GetPGClassTupleForRelationName(const char *relation_name) {
  Relation pg_class_rel;
  HeapTuple tuple = NULL;
  HeapScanDesc scan;

  PelotonStartTransactionCommand();

  // Open pg_class table
  pg_class_rel = heap_open(RelationRelationId, AccessShareLock);

  // Search the pg_class table with given relation name
  scan = heap_beginscan_catalog(pg_class_rel, 0, NULL);

  while (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection))) {
    Form_pg_class pgclass = (Form_pg_class)GETSTRUCT(tuple);

    if (pgclass->relnamespace == PG_PUBLIC_NAMESPACE) {
      if (strcmp(NameStr(pgclass->relname), relation_name) == 0) {
        // We need to end scan and close heap
        break;
      }
    }
  }

  heap_endscan(scan);
  heap_close(pg_class_rel, AccessShareLock);

  PelotonCommitTransactionCommand();

  return tuple;
}

/**
 * @brief Getting the relation name
 * @param relation_id relation id
 * @return Tuple if valid relation_id, otherwise null
 */
char *Bridge::GetRelationName(Oid relation_id) {
  HeapTuple tuple;
  Form_pg_class pg_class;
  char *relation_name;

  tuple = GetPGClassTupleForRelationOid(relation_id);
  if (!HeapTupleIsValid(tuple)) {
    return NULL;
  }

  // Get relation name
  pg_class = (Form_pg_class)GETSTRUCT(tuple);
  relation_name = NameStr(pg_class->relname);

  return relation_name;
}

/*
 * given a table name, look up the OID
 * @param table_name table name
 * @return relation id, if relation is valid, 0 otherewise
 */
Oid Bridge::GetRelationOid(const char *relation_name) {
  Oid relation_oid = InvalidOid;
  HeapTuple tuple;

  tuple = GetPGClassTupleForRelationName(relation_name);
  if (!HeapTupleIsValid(tuple)) {
    return InvalidOid;
  }

  // Get relation oid
  relation_oid = HeapTupleHeaderGetOid(tuple->t_data);

  return relation_oid;
}

//===--------------------------------------------------------------------===//
// Catalog information
//===--------------------------------------------------------------------===//

/**
 * @brief Getting the number of attributes.
 * @param relation_id relation id
 * @return num_atts if valid relation_id, otherwise -1
 */
int Bridge::GetNumberOfAttributes(Oid relation_id) {
  HeapTuple tuple;
  Form_pg_class pg_class;
  int num_atts = -1;

  tuple = GetPGClassTupleForRelationOid(relation_id);

  if (!HeapTupleIsValid(tuple)) {
    return num_atts;
  }

  pg_class = (Form_pg_class)GETSTRUCT(tuple);

  // Get number of attributes
  num_atts = pg_class->relnatts;

  return num_atts;
}

/**
 * @brief Getting the number of tuples.
 * @param relation_id relation id
 * @return num_tuples if valid relation_id, otherwise -1
 */
float Bridge::GetNumberOfTuples(Oid relation_id) {
  HeapTuple tuple;
  Form_pg_class pg_class;
  float num_tuples;

  tuple = GetPGClassTupleForRelationOid(relation_id);
  if (!HeapTupleIsValid(tuple)) {
    return -1;
  }
  pg_class = (Form_pg_class)GETSTRUCT(tuple);

  // Get number of tuples
  num_tuples = pg_class->reltuples;

  return num_tuples;
}

/**
 * @brief Getting the current database Oid
 * @return MyDatabaseId
 */
Oid Bridge::GetCurrentDatabaseOid(void) { return MyDatabaseId; }

/**
 * @brief Printing the current database information out
 */
Oid Bridge::GetDbInfo(void) {
  printf("Mydatabase Id %u \n", MyDatabaseId);
  printf("MydatabaseTableSpace Id %u \n", MyDatabaseTableSpace);
  printf("Mydatabase path %s \n", DatabasePath);
}

/**
 * @Determine whether table exists in the *current* database or not
 * @param table_name table name
 * @return true or false depending on whether table exists or not.
 */
bool Bridge::RelationExists(const char *relation_name) {
  HeapTuple tuple;

  tuple = GetPGClassTupleForRelationName(relation_name);
  if (!HeapTupleIsValid(tuple)) {
    return false;
  }

  return true;
}

//===--------------------------------------------------------------------===//
// Table lists
//===--------------------------------------------------------------------===//

/**
 * @brief Print all tables in *current* database using catalog table pg_class
 */
void Bridge::GetTableList(bool catalog_only) {
  Relation pg_class_rel;
  HeapScanDesc scan;
  HeapTuple tuple;

  PelotonStartTransactionCommand();

  // Scan pg class table
  pg_class_rel = heap_open(RelationRelationId, AccessShareLock);
  scan = heap_beginscan_catalog(pg_class_rel, 0, NULL);

  while (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection))) {
    Form_pg_class pgclass = (Form_pg_class)GETSTRUCT(tuple);

    // Check if we only need catalog tables or not ?
    if (catalog_only == false) {
      elog(LOG, "pgclass->relname :: %s ", NameStr(pgclass->relname));
    } else if (pgclass->relnamespace == PG_PUBLIC_NAMESPACE) {
      elog(LOG, "pgclass->relname :: %s ", NameStr(pgclass->relname));
    }
  }

  heap_endscan(scan);
  heap_close(pg_class_rel, AccessShareLock);

  PelotonCommitTransactionCommand();
}

/**
 * @brief Print all databases using catalog table pg_database
 */
void Bridge::GetDatabaseList(void) {
  Relation pg_database_rel;
  HeapScanDesc scan;
  HeapTuple tup;

  PelotonStartTransactionCommand();

  // Scan pg database table
  pg_database_rel = heap_open(DatabaseRelationId, AccessShareLock);
  scan = heap_beginscan_catalog(pg_database_rel, 0, NULL);

  while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) {
    Form_pg_database pg_database = (Form_pg_database)GETSTRUCT(tup);
    Oid database_oid = HeapTupleHeaderGetOid(tup->t_data);
    elog(LOG, "pgdatabase->datname  :: %s oid %d ",
         NameStr(pg_database->datname), (int)database_oid);
  }

  heap_endscan(scan);
  heap_close(pg_database_rel, AccessShareLock);

  PelotonCommitTransactionCommand();
}

//===--------------------------------------------------------------------===//
// Setters
//===--------------------------------------------------------------------===//

/**
 * @brief Setting the number of tuples.
 * @param relation_id relation id
 * @param num_tuples number of tuples
 */
void Bridge::SetNumberOfTuples(Oid relation_id, float num_tuples) {
  assert(relation_id);

  Relation pg_class_rel;
  HeapTuple tuple;
  Form_pg_class pgclass;

  PelotonStartTransactionCommand();

  // Open target table in exclusive mode
  pg_class_rel = heap_open(RelationRelationId, RowExclusiveLock);
  tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relation_id));
  if (!HeapTupleIsValid(tuple)) {
    elog(DEBUG2, "cache lookup failed for relation %u", relation_id);
  }else{
    pgclass = (Form_pg_class) GETSTRUCT(tuple);
    pgclass->reltuples = (float4) num_tuples;
    pgclass->relpages = (int32) 1;

    // update tuple
    simple_heap_update(pg_class_rel, &tuple->t_self, tuple);

    /* keep the catalog indexes up to date */
    CatalogUpdateIndexes(pg_class_rel, tuple);

    heap_freetuple(tuple);
  }

  heap_close(pg_class_rel, RowExclusiveLock);
  PelotonCommitTransactionCommand();
}

//===--------------------------------------------------------------------===//
// Wrapper
//===--------------------------------------------------------------------===//

void Bridge::PelotonStartTransactionCommand(){
  StartTransactionCommand();
}

void Bridge::PelotonCommitTransactionCommand(){
  CommitTransactionCommand();
  SetCurrentResourceOwner();
}

void Bridge::SetCurrentResourceOwner(){
  // Set the resource owner
  CurrentResourceOwner = ResourceOwnerCreate(NULL, "Peloton");
}

}  // namespace bridge
}  // namespace peloton
<commit_msg>Added warning message for bridge function<commit_after>/**
 * @brief Implementation of bridge.
 *
 * These utilities allow us to manage Postgres metadata.
 *
 * Copyright(c) 2015, CMU
 */

#include <iostream>
#include <assert.h>
#include <sys/types.h>
#include <unistd.h>

#include "backend/bridge/ddl/bridge.h"
#include "backend/common/logger.h"

#include "postgres.h"
#include "c.h"
#include "miscadmin.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "access/xact.h"
#include "catalog/indexing.h"
#include "catalog/pg_attribute.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_class.h"
#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_type.h"
#include "common/fe_memutils.h"
#include "utils/rel.h"
#include "utils/ruleutils.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
#include "parser/parse_type.h"

namespace peloton {
namespace bridge {

//===--------------------------------------------------------------------===//
// Getters
//===--------------------------------------------------------------------===//

/**
 * @brief Get the pg class tuple
 * @param tuple relevant tuple if it exists, NULL otherwise
 */
HeapTuple Bridge::GetPGClassTupleForRelationOid(Oid relation_id) {
  LOG_WARN("Do not use bridge function in Peloton !!! \n");
  Relation pg_class_rel;
  HeapTuple tuple = NULL;

  PelotonStartTransactionCommand();

  // Open pg_class table
  pg_class_rel = heap_open(RelationRelationId, AccessShareLock);

  // Search the pg_class table with given relation id
  tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relation_id));
  if (!HeapTupleIsValid(tuple)) {
    elog(DEBUG2, "cache lookup failed for relation %u", relation_id);
    // Don't break here, we need to close heap and commit.
  }

  heap_close(pg_class_rel, AccessShareLock);

  PelotonCommitTransactionCommand();

  return tuple;
}

/**
 * @brief Get the pg class tuple
 * @param tuple relevant tuple if it exists, NULL otherwise
 */
HeapTuple Bridge::GetPGClassTupleForRelationName(const char *relation_name) {
  LOG_WARN("Do not use bridge function in Peloton !!! \n");
  Relation pg_class_rel;
  HeapTuple tuple = NULL;
  HeapScanDesc scan;

  PelotonStartTransactionCommand();

  // Open pg_class table
  pg_class_rel = heap_open(RelationRelationId, AccessShareLock);

  // Search the pg_class table with given relation name
  scan = heap_beginscan_catalog(pg_class_rel, 0, NULL);

  while (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection))) {
    Form_pg_class pgclass = (Form_pg_class)GETSTRUCT(tuple);

    if (pgclass->relnamespace == PG_PUBLIC_NAMESPACE) {
      if (strcmp(NameStr(pgclass->relname), relation_name) == 0) {
        // We need to end scan and close heap
        break;
      }
    }
  }

  heap_endscan(scan);
  heap_close(pg_class_rel, AccessShareLock);

  PelotonCommitTransactionCommand();

  return tuple;
}

/**
 * @brief Getting the relation name
 * @param relation_id relation id
 * @return Tuple if valid relation_id, otherwise null
 */
char *Bridge::GetRelationName(Oid relation_id) {
  LOG_WARN("Do not use bridge function in Peloton !!! \n");
  HeapTuple tuple;
  Form_pg_class pg_class;
  char *relation_name;

  tuple = GetPGClassTupleForRelationOid(relation_id);
  if (!HeapTupleIsValid(tuple)) {
    return NULL;
  }

  // Get relation name
  pg_class = (Form_pg_class)GETSTRUCT(tuple);
  relation_name = NameStr(pg_class->relname);

  return relation_name;
}

/*
 * given a table name, look up the OID
 * @param table_name table name
 * @return relation id, if relation is valid, 0 otherewise
 */
Oid Bridge::GetRelationOid(const char *relation_name) {
  LOG_WARN("Do not use bridge function in Peloton !!! \n");
  Oid relation_oid = InvalidOid;
  HeapTuple tuple;

  tuple = GetPGClassTupleForRelationName(relation_name);
  if (!HeapTupleIsValid(tuple)) {
    return InvalidOid;
  }

  // Get relation oid
  relation_oid = HeapTupleHeaderGetOid(tuple->t_data);

  return relation_oid;
}

//===--------------------------------------------------------------------===//
// Catalog information
//===--------------------------------------------------------------------===//

/**
 * @brief Getting the number of attributes.
 * @param relation_id relation id
 * @return num_atts if valid relation_id, otherwise -1
 */
int Bridge::GetNumberOfAttributes(Oid relation_id) {
  HeapTuple tuple;
  Form_pg_class pg_class;
  int num_atts = -1;

  tuple = GetPGClassTupleForRelationOid(relation_id);

  if (!HeapTupleIsValid(tuple)) {
    return num_atts;
  }

  pg_class = (Form_pg_class)GETSTRUCT(tuple);

  // Get number of attributes
  num_atts = pg_class->relnatts;

  return num_atts;
}

/**
 * @brief Getting the number of tuples.
 * @param relation_id relation id
 * @return num_tuples if valid relation_id, otherwise -1
 */
float Bridge::GetNumberOfTuples(Oid relation_id) {
  LOG_WARN("Do not use bridge function in Peloton !!! \n");
  HeapTuple tuple;
  Form_pg_class pg_class;
  float num_tuples;

  tuple = GetPGClassTupleForRelationOid(relation_id);
  if (!HeapTupleIsValid(tuple)) {
    return -1;
  }
  pg_class = (Form_pg_class)GETSTRUCT(tuple);

  // Get number of tuples
  num_tuples = pg_class->reltuples;

  return num_tuples;
}

/**
 * @brief Getting the current database Oid
 * @return MyDatabaseId
 */
Oid Bridge::GetCurrentDatabaseOid(void) { return MyDatabaseId; }

/**
 * @brief Printing the current database information out
 */
Oid Bridge::GetDbInfo(void) {
  LOG_WARN("Do not use bridge function in Peloton !!! \n");
  printf("Mydatabase Id %u \n", MyDatabaseId);
  printf("MydatabaseTableSpace Id %u \n", MyDatabaseTableSpace);
  printf("Mydatabase path %s \n", DatabasePath);
}

/**
 * @Determine whether table exists in the *current* database or not
 * @param table_name table name
 * @return true or false depending on whether table exists or not.
 */
bool Bridge::RelationExists(const char *relation_name) {
  LOG_WARN("Do not use bridge function in Peloton !!! \n");
  HeapTuple tuple;

  tuple = GetPGClassTupleForRelationName(relation_name);
  if (!HeapTupleIsValid(tuple)) {
    return false;
  }

  return true;
}

//===--------------------------------------------------------------------===//
// Table lists
//===--------------------------------------------------------------------===//

/**
 * @brief Print all tables in *current* database using catalog table pg_class
 */
void Bridge::GetTableList(bool catalog_only) {
  LOG_WARN("Do not use bridge function in Peloton !!! \n");
  Relation pg_class_rel;
  HeapScanDesc scan;
  HeapTuple tuple;

  PelotonStartTransactionCommand();

  // Scan pg class table
  pg_class_rel = heap_open(RelationRelationId, AccessShareLock);
  scan = heap_beginscan_catalog(pg_class_rel, 0, NULL);

  while (HeapTupleIsValid(tuple = heap_getnext(scan, ForwardScanDirection))) {
    Form_pg_class pgclass = (Form_pg_class)GETSTRUCT(tuple);

    // Check if we only need catalog tables or not ?
    if (catalog_only == false) {
      elog(LOG, "pgclass->relname :: %s ", NameStr(pgclass->relname));
    } else if (pgclass->relnamespace == PG_PUBLIC_NAMESPACE) {
      elog(LOG, "pgclass->relname :: %s ", NameStr(pgclass->relname));
    }
  }

  heap_endscan(scan);
  heap_close(pg_class_rel, AccessShareLock);

  PelotonCommitTransactionCommand();
}

/**
 * @brief Print all databases using catalog table pg_database
 */
void Bridge::GetDatabaseList(void) {
  LOG_WARN("Do not use bridge function in Peloton !!! \n");
  Relation pg_database_rel;
  HeapScanDesc scan;
  HeapTuple tup;

  PelotonStartTransactionCommand();

  // Scan pg database table
  pg_database_rel = heap_open(DatabaseRelationId, AccessShareLock);
  scan = heap_beginscan_catalog(pg_database_rel, 0, NULL);

  while (HeapTupleIsValid(tup = heap_getnext(scan, ForwardScanDirection))) {
    Form_pg_database pg_database = (Form_pg_database)GETSTRUCT(tup);
    Oid database_oid = HeapTupleHeaderGetOid(tup->t_data);
    elog(LOG, "pgdatabase->datname  :: %s oid %d ",
         NameStr(pg_database->datname), (int)database_oid);
  }

  heap_endscan(scan);
  heap_close(pg_database_rel, AccessShareLock);

  PelotonCommitTransactionCommand();
}

//===--------------------------------------------------------------------===//
// Setters
//===--------------------------------------------------------------------===//

/**
 * @brief Setting the number of tuples.
 * @param relation_id relation id
 * @param num_tuples number of tuples
 */
void Bridge::SetNumberOfTuples(Oid relation_id, float num_tuples) {
  LOG_WARN("Do not use bridge function in Peloton !!! \n");
  assert(relation_id);

  Relation pg_class_rel;
  HeapTuple tuple;
  Form_pg_class pgclass;

  PelotonStartTransactionCommand();

  // Open target table in exclusive mode
  pg_class_rel = heap_open(RelationRelationId, RowExclusiveLock);
  tuple = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relation_id));
  if (!HeapTupleIsValid(tuple)) {
    elog(DEBUG2, "cache lookup failed for relation %u", relation_id);
  }else{
    pgclass = (Form_pg_class) GETSTRUCT(tuple);
    pgclass->reltuples = (float4) num_tuples;
    pgclass->relpages = (int32) 1;

    // update tuple
    simple_heap_update(pg_class_rel, &tuple->t_self, tuple);

    /* keep the catalog indexes up to date */
    CatalogUpdateIndexes(pg_class_rel, tuple);

    heap_freetuple(tuple);
  }

  heap_close(pg_class_rel, RowExclusiveLock);
  PelotonCommitTransactionCommand();
}

//===--------------------------------------------------------------------===//
// Wrapper
//===--------------------------------------------------------------------===//

void Bridge::PelotonStartTransactionCommand(){
  StartTransactionCommand();
}

void Bridge::PelotonCommitTransactionCommand(){
  CommitTransactionCommand();
  SetCurrentResourceOwner();
}

void Bridge::SetCurrentResourceOwner(){
  // Set the resource owner
  CurrentResourceOwner = ResourceOwnerCreate(NULL, "Peloton");
}

}  // namespace bridge
}  // namespace peloton
<|endoftext|>


<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#pragma once

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wattributes"
#include <boost/stacktrace.hpp>
#pragma GCC diagnostic pop
#include <common/defines.hpp>
#include <af/defines.h>

#include <cassert>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

class AfError : public std::logic_error {
    std::string functionName;
    std::string fileName;
    int lineNumber;
    af_err error;
    boost::stacktrace::stacktrace st_;
    AfError();

   public:
    AfError(const char* const func, const char* const file, const int line,
            const char* const message, af_err err,
            boost::stacktrace::stacktrace st);

    AfError(std::string func, std::string file, const int line,
            const std::string& message, af_err err,
            boost::stacktrace::stacktrace st);

    AfError(const AfError& other) noexcept = delete;
    AfError(AfError&& other) noexcept      = default;

    const std::string& getFunctionName() const noexcept;

    const std::string& getFileName() const noexcept;

    const boost::stacktrace::stacktrace& getStacktrace() const noexcept {
        return st_;
    };

    int getLine() const noexcept;

    af_err getError() const noexcept;

    virtual ~AfError() noexcept;
};

// TODO: Perhaps add a way to return supported types
class TypeError : public AfError {
    int argIndex;
    std::string errTypeName;
    TypeError();

   public:
    TypeError(const char* const func, const char* const file, const int line,
              const int index, const af_dtype type,
              const boost::stacktrace::stacktrace st);

    TypeError(TypeError&& other) noexcept = default;

    const std::string& getTypeName() const noexcept;

    int getArgIndex() const noexcept;

    ~TypeError() noexcept {}
};

class ArgumentError : public AfError {
    int argIndex;
    std::string expected;
    ArgumentError();

   public:
    ArgumentError(const char* const func, const char* const file,
                  const int line, const int index,
                  const char* const expectString,
                  const boost::stacktrace::stacktrace st);
    ArgumentError(ArgumentError&& other) noexcept = default;

    const std::string& getExpectedCondition() const noexcept;

    int getArgIndex() const noexcept;

    ~ArgumentError() noexcept {}
};

class SupportError : public AfError {
    std::string backend;
    SupportError();

   public:
    SupportError(const char* const func, const char* const file, const int line,
                 const char* const back,
                 const boost::stacktrace::stacktrace st);
    SupportError(SupportError&& other) noexcept = default;

    ~SupportError() noexcept {}

    const std::string& getBackendName() const noexcept;
};

class DimensionError : public AfError {
    int argIndex;
    std::string expected;
    DimensionError();

   public:
    DimensionError(const char* const func, const char* const file,
                   const int line, const int index,
                   const char* const expectString,
                   const boost::stacktrace::stacktrace& st);
    DimensionError(DimensionError&& other) noexcept = default;

    const std::string& getExpectedCondition() const noexcept;

    int getArgIndex() const noexcept;

    ~DimensionError() noexcept {}
};

af_err processException();

af_err set_global_error_string(const std::string& msg,
                               af_err err = AF_ERR_UNKNOWN);

#define DIM_ASSERT(INDEX, COND)                                        \
    do {                                                               \
        if ((COND) == false) {                                         \
            throw DimensionError(__PRETTY_FUNCTION__, __AF_FILENAME__, \
                                 __LINE__, INDEX, #COND,               \
                                 boost::stacktrace::stacktrace());     \
        }                                                              \
    } while (0)

#define ARG_ASSERT(INDEX, COND)                                       \
    do {                                                              \
        if ((COND) == false) {                                        \
            throw ArgumentError(__PRETTY_FUNCTION__, __AF_FILENAME__, \
                                __LINE__, INDEX, #COND,               \
                                boost::stacktrace::stacktrace());     \
        }                                                             \
    } while (0)

#define TYPE_ERROR(INDEX, type)                                                \
    do {                                                                       \
        throw TypeError(__PRETTY_FUNCTION__, __AF_FILENAME__, __LINE__, INDEX, \
                        type, boost::stacktrace::stacktrace());                \
    } while (0)

#define AF_ERROR(MSG, ERR_TYPE)                                            \
    do {                                                                   \
        throw AfError(__PRETTY_FUNCTION__, __AF_FILENAME__, __LINE__, MSG, \
                      ERR_TYPE, boost::stacktrace::stacktrace());          \
    } while (0)

#define AF_RETURN_ERROR(MSG, ERR_TYPE)                                       \
    do {                                                                     \
        std::stringstream s;                                                 \
        s << "Error in " << __PRETTY_FUNCTION__ << "\n"                      \
          << "In file " << __AF_FILENAME__ << ":" << __LINE__ << ": " << MSG \
          << "\n"                                                            \
          << boost::stacktrace::stacktrace();                                \
        return set_global_error_string(s.str(), ERR_TYPE);                   \
    } while (0)

#define TYPE_ASSERT(COND)                                       \
    do {                                                        \
        if ((COND) == false) {                                  \
            AF_ERROR("Type mismatch inputs", AF_ERR_DIFF_TYPE); \
        }                                                       \
    } while (0)

#define AF_ASSERT(COND, MESSAGE) assert(MESSAGE&& COND)

#define CATCHALL                   \
    catch (...) {                  \
        return processException(); \
    }

#define AF_CHECK(fn)                                                        \
    do {                                                                    \
        af_err __err = fn;                                                  \
        if (__err == AF_SUCCESS) break;                                     \
        throw AfError(__PRETTY_FUNCTION__, __AF_FILENAME__, __LINE__, "\n", \
                      __err, boost::stacktrace::stacktrace());              \
    } while (0)

static const int MAX_ERR_SIZE = 1024;
std::string& get_global_error_string() noexcept;

namespace common {

bool& is_stacktrace_enabled() noexcept;

}  // namespace common
<commit_msg>Fix warning in older versions of boost stacktrace<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#pragma once

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wattributes"
#pragma GCC diagnostic ignored "-Wparentheses"
#include <boost/stacktrace.hpp>
#pragma GCC diagnostic pop
#include <common/defines.hpp>
#include <af/defines.h>

#include <cassert>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

class AfError : public std::logic_error {
    std::string functionName;
    std::string fileName;
    int lineNumber;
    af_err error;
    boost::stacktrace::stacktrace st_;
    AfError();

   public:
    AfError(const char* const func, const char* const file, const int line,
            const char* const message, af_err err,
            boost::stacktrace::stacktrace st);

    AfError(std::string func, std::string file, const int line,
            const std::string& message, af_err err,
            boost::stacktrace::stacktrace st);

    AfError(const AfError& other) noexcept = delete;
    AfError(AfError&& other) noexcept      = default;

    const std::string& getFunctionName() const noexcept;

    const std::string& getFileName() const noexcept;

    const boost::stacktrace::stacktrace& getStacktrace() const noexcept {
        return st_;
    };

    int getLine() const noexcept;

    af_err getError() const noexcept;

    virtual ~AfError() noexcept;
};

// TODO: Perhaps add a way to return supported types
class TypeError : public AfError {
    int argIndex;
    std::string errTypeName;
    TypeError();

   public:
    TypeError(const char* const func, const char* const file, const int line,
              const int index, const af_dtype type,
              const boost::stacktrace::stacktrace st);

    TypeError(TypeError&& other) noexcept = default;

    const std::string& getTypeName() const noexcept;

    int getArgIndex() const noexcept;

    ~TypeError() noexcept {}
};

class ArgumentError : public AfError {
    int argIndex;
    std::string expected;
    ArgumentError();

   public:
    ArgumentError(const char* const func, const char* const file,
                  const int line, const int index,
                  const char* const expectString,
                  const boost::stacktrace::stacktrace st);
    ArgumentError(ArgumentError&& other) noexcept = default;

    const std::string& getExpectedCondition() const noexcept;

    int getArgIndex() const noexcept;

    ~ArgumentError() noexcept {}
};

class SupportError : public AfError {
    std::string backend;
    SupportError();

   public:
    SupportError(const char* const func, const char* const file, const int line,
                 const char* const back,
                 const boost::stacktrace::stacktrace st);
    SupportError(SupportError&& other) noexcept = default;

    ~SupportError() noexcept {}

    const std::string& getBackendName() const noexcept;
};

class DimensionError : public AfError {
    int argIndex;
    std::string expected;
    DimensionError();

   public:
    DimensionError(const char* const func, const char* const file,
                   const int line, const int index,
                   const char* const expectString,
                   const boost::stacktrace::stacktrace& st);
    DimensionError(DimensionError&& other) noexcept = default;

    const std::string& getExpectedCondition() const noexcept;

    int getArgIndex() const noexcept;

    ~DimensionError() noexcept {}
};

af_err processException();

af_err set_global_error_string(const std::string& msg,
                               af_err err = AF_ERR_UNKNOWN);

#define DIM_ASSERT(INDEX, COND)                                        \
    do {                                                               \
        if ((COND) == false) {                                         \
            throw DimensionError(__PRETTY_FUNCTION__, __AF_FILENAME__, \
                                 __LINE__, INDEX, #COND,               \
                                 boost::stacktrace::stacktrace());     \
        }                                                              \
    } while (0)

#define ARG_ASSERT(INDEX, COND)                                       \
    do {                                                              \
        if ((COND) == false) {                                        \
            throw ArgumentError(__PRETTY_FUNCTION__, __AF_FILENAME__, \
                                __LINE__, INDEX, #COND,               \
                                boost::stacktrace::stacktrace());     \
        }                                                             \
    } while (0)

#define TYPE_ERROR(INDEX, type)                                                \
    do {                                                                       \
        throw TypeError(__PRETTY_FUNCTION__, __AF_FILENAME__, __LINE__, INDEX, \
                        type, boost::stacktrace::stacktrace());                \
    } while (0)

#define AF_ERROR(MSG, ERR_TYPE)                                            \
    do {                                                                   \
        throw AfError(__PRETTY_FUNCTION__, __AF_FILENAME__, __LINE__, MSG, \
                      ERR_TYPE, boost::stacktrace::stacktrace());          \
    } while (0)

#define AF_RETURN_ERROR(MSG, ERR_TYPE)                                       \
    do {                                                                     \
        std::stringstream s;                                                 \
        s << "Error in " << __PRETTY_FUNCTION__ << "\n"                      \
          << "In file " << __AF_FILENAME__ << ":" << __LINE__ << ": " << MSG \
          << "\n"                                                            \
          << boost::stacktrace::stacktrace();                                \
        return set_global_error_string(s.str(), ERR_TYPE);                   \
    } while (0)

#define TYPE_ASSERT(COND)                                       \
    do {                                                        \
        if ((COND) == false) {                                  \
            AF_ERROR("Type mismatch inputs", AF_ERR_DIFF_TYPE); \
        }                                                       \
    } while (0)

#define AF_ASSERT(COND, MESSAGE) assert(MESSAGE&& COND)

#define CATCHALL                   \
    catch (...) {                  \
        return processException(); \
    }

#define AF_CHECK(fn)                                                        \
    do {                                                                    \
        af_err __err = fn;                                                  \
        if (__err == AF_SUCCESS) break;                                     \
        throw AfError(__PRETTY_FUNCTION__, __AF_FILENAME__, __LINE__, "\n", \
                      __err, boost::stacktrace::stacktrace());              \
    } while (0)

static const int MAX_ERR_SIZE = 1024;
std::string& get_global_error_string() noexcept;

namespace common {

bool& is_stacktrace_enabled() noexcept;

}  // namespace common
<|endoftext|>