2015-12-14 2 views
0

В настоящее время я использую Witty и DBO с SQLite3 внутри проекта, и теперь мне нужно присоединиться к связанной таблице, чтобы получить только количество строк.ORM get join table count count

Столы

CREATE TABLE "rfnode" (
    "mac" varchar(16) not null, 
    "zone" integer not null, 
    "subZone" integer not null, 
    "unit" text not null, 
    "pwm" integer not null, 
    "led" integer not null, 
    "network" integer not null, 
    "lastContact" text, 
    "ioConfiguration" integer not null, 
    primary key ("mac") 
) 

CREATE TABLE "nodemeasure" (
    "id" integer primary key autoincrement, 
    "mac" text not null, 
    "type" integer not null, 
    "date" text, 
    "batchDate" text, 
    "value" real not null 
) 

Обычно SQL запрос:

SELECT 
    rn.*, 
    COUNT(nm.id) AS measuresCount 
FROM rfnode rn 
LEFT JOIN nodemeasure nm 
    ON nm.mac = rn.mac 
GROUP BY rn.mac 

Теперь проблема заключается в том, что я не могу понять, как сделать запрос и получить результат с помощью Wt/Библиотека DBO.

Первая попытка

class RFNode 
{ 
    public: 
     std::string mac, unit; 
     int zone = 0, subZone = 0, pwm = 0, led = 0, network = 0, ioConfiguration = 0, measuresCount = 0; 
     Wt::WDateTime lastContact; 

     RFNode() 
     { 
      mac    = ""; 
      zone   = 0; 
      subZone   = 0; 
      unit   = ""; 
      pwm    = 8; 
      led    = 8; 
      network   = 0; 
      ioConfiguration = 0; 
      measuresCount = 0; 
     } 

     RFNode(std::string p_sMAC, int p_nZone, int p_nSubZone, std::string p_sUnit, int p_nPWM, int p_nLED, int p_nNetwork, Wt::WDateTime p_oLastContact, int p_nIOConfiguration, int p_nMeasuresCount = 0) 
     { 
      mac    = p_sMAC; 
      zone   = p_nZone; 
      subZone   = p_nSubZone; 
      unit   = p_sUnit; 
      pwm    = p_nPWM; 
      led    = p_nLED; 
      network   = p_nNetwork; 
      lastContact  = p_oLastContact; 
      ioConfiguration = p_nIOConfiguration; 
      measuresCount = p_nMeasuresCount; 
     } 

     template<class Action> 
     void persist(Action& a) 
     { 
      dbo::id(a,  mac,   "mac",16); 
      dbo::field(a, zone,   "zone"); 
      dbo::field(a, subZone,  "subZone"); 
      dbo::field(a, unit,   "unit"); 
      dbo::field(a, pwm,   "pwm"); 
      dbo::field(a, led,   "led"); 
      dbo::field(a, network,  "network"); 
      dbo::field(a, lastContact, "lastContact"); 
      dbo::field(a, ioConfiguration,"ioConfiguration"); 
      dbo::field(a, measuresCount, "measuresCount"); 
     }; 
}; 

с запросом:

Wt::Dbo::collection<Wt::Dbo::ptr<RFNode>> lTemp = m_oSession.query<Wt::Dbo::ptr<RFNode>>("SELECT rn.*, COUNT(nm.id) AS measuresCount FROM rfnode rn LEFT JOIN nodemeasure nm ON nm.mac = rn.mac").resultList(); 

это приводит к Session::query(): too many aliases for result.

Вторая попытка

же класс RFNode, за исключением того поля measuresCount удалены.

typedef Wt::Dbo::ptr_tuple<RFNode, int>::type RFNodeJoin; 
     typedef Wt::Dbo::collection<RFNodeJoin> RFNodeJoinC; 

     RFNodeJoinC lTemp = m_oSession.query<RFNodeJoin>("SELECT rn.*, COUNT(nm.id) AS measuresCount FROM rfnode rn LEFT JOIN nodemeasure nm ON nm.mac = rn.mac GROUP BY rn.mac").resultList(); 

     std::vector<RFNodeJoin> lTransition(lTemp.begin(),lTemp.end()); 

но он не компилируется, в результате ошибки: error: request for member ‘persist’ in ‘obj’, which is of non-class type ‘int’. Полагаю, мне нужно сопоставить один класс за таблицу, но поскольку я хочу подсчет и никаких существующих полей, я не думаю, что класс int выполнит эту работу.

ответ

0

Наконец методом проб и ошибок я нашел решение ...

Во-первых, RFNode класс не имеет поле measuresCount больше.

Запроса и итерации выполняются следующим образом:

Wt::Dbo::collection<boost::tuple<Wt::Dbo::ptr<RFNode>, int>> lTemp = m_oSession.query<boost::tuple<Wt::Dbo::ptr<RFNode>, int>>("SELECT rn, COUNT(nm.id) FROM rfnode rn LEFT JOIN nodemeasure nm ON nm.mac = rn.mac GROUP BY rn.mac").resultList(); 

for(Wt::Dbo::collection<boost::tuple<Wt::Dbo::ptr<RFNode>, int>>::const_iterator i = lTemp.begin();i != lTemp.end();++i) 
{ 
    Wt::Dbo::ptr<RFNode> pRFNode; 
    int nNodeMeasureCount; 

    boost::tie(pRFNode,nNodeMeasureCount) = *i; 

    lNodes.push_back(
      RFNode(
        pRFNode->mac, 
        pRFNode->zone, 
        pRFNode->subZone, 
        pRFNode->unit, 
        pRFNode->pwm, 
        pRFNode->led, 
        pRFNode->network, 
        pRFNode->lastContact, 
        pRFNode->ioConfiguration, 
        nNodeMeasureCount 
      ) 
    ); 
} 

Надеется, что это поможет кому-нибудь!