PyResult ContractMgrService::Handle_GetContractList( PyCallArgs& call ) { sLog.Debug( "ContractMgrService", "Called GetContractListForOwner stub." ); // Call_GetContractListForOwner arg; PyDict* _contract = new PyDict; /*if( !arg.Decode(&call.tuple) ) { codelog(SERVICE__ERROR, "%s: Bad arguments to GetContractListForOwner", call.client->GetName()); return NULL; }*/ // Manual creation of a CRowset, i hate doing this -.-" DBRowDescriptor *header = new DBRowDescriptor(); header->AddColumn( "contractID", DBTYPE_I4); header->AddColumn( "issuerID", DBTYPE_I4); header->AddColumn( "issuerCorpID", DBTYPE_I4 ); header->AddColumn( "type", DBTYPE_UI1 ); header->AddColumn( "availability", DBTYPE_I4 ); header->AddColumn( "assigneeID", DBTYPE_I4 ); header->AddColumn( "numDays", DBTYPE_I4 ); header->AddColumn( "startStationID", DBTYPE_I4 ); header->AddColumn( "endStationID", DBTYPE_I4 ); header->AddColumn( "startSolarSystemID", DBTYPE_I4 ); header->AddColumn( "endSolarSystemID", DBTYPE_I4 ); header->AddColumn( "startRegionID", DBTYPE_I4 ); header->AddColumn( "endRegionID", DBTYPE_I4 ); header->AddColumn( "price", DBTYPE_CY ); header->AddColumn( "reward", DBTYPE_CY ); header->AddColumn( "collateral", DBTYPE_CY ); header->AddColumn( "title", DBTYPE_WSTR ); header->AddColumn( "description", DBTYPE_WSTR ); header->AddColumn( "forCorp", DBTYPE_BOOL ); header->AddColumn( "status", DBTYPE_UI1 ); header->AddColumn( "acceptorID", DBTYPE_I4 ); header->AddColumn( "dateIssued", DBTYPE_FILETIME ); header->AddColumn( "dateExpired", DBTYPE_FILETIME ); header->AddColumn( "dateAccepted", DBTYPE_FILETIME ); header->AddColumn( "dateCompleted", DBTYPE_FILETIME ); header->AddColumn( "volume", DBTYPE_R8 ); header->AddColumn( "issuerAllianceID", DBTYPE_I4 ); header->AddColumn( "issuerWalletKey", DBTYPE_I4 ); CRowSet *rowset = new CRowSet( &header ); PyList* fieldData = new PyList; DBResultRow row; std::map<uint32, ContractRef>::const_iterator cur, end; std::map<uint32, ContractRef> contracts = m_contractManager->GetContractList(); cur = contracts.begin(); end = contracts.end(); util_Rowset res; for(; cur != end; cur++ ) { ContractRef contract = cur->second; PyPackedRow* into = rowset->NewRow(); fieldData->AddItemInt( contract->contractID() ); fieldData->AddItemInt( contract->issuerID() ); fieldData->AddItemInt( contract->issuerCorpID() ); fieldData->AddItemInt( contract->type() ); fieldData->AddItemInt( contract->avail() ); fieldData->AddItemInt( contract->assigneeID() ); fieldData->AddItemInt( contract->expiretime() ); fieldData->AddItemInt( contract->duration() ); fieldData->AddItemInt( contract->startStationID() ); fieldData->AddItemInt( contract->endStationID() ); fieldData->AddItemInt( contract->startSolarSystemID() ); fieldData->AddItemInt( contract->endSolarSystemID() ); fieldData->AddItemInt( contract->startRegionID() ); fieldData->AddItemInt( contract->endRegionID() ); fieldData->AddItemInt( contract->price() ); fieldData->AddItemInt( contract->reward() ); fieldData->AddItemInt( contract->collateral() ); fieldData->AddItemString( contract->title().c_str() ); fieldData->AddItemString( contract->description().c_str() ); fieldData->AddItemInt( contract->forCorp() ); fieldData->AddItemInt( contract->status() ); fieldData->AddItemInt( contract->isAccepted() ); fieldData->AddItemInt( contract->acceptorID() ); fieldData->AddItemInt( contract->dateIssued() ); fieldData->AddItemInt( contract->dateExpired() ); fieldData->AddItemInt( contract->dateAccepted() ); fieldData->AddItemInt( contract->dateCompleted() ); fieldData->AddItemInt( contract->volume() ); into->SetField( contract->contractID(), fieldData ); fieldData = new PyList; res.lines = new PyList; res.header.clear(); fieldData = new PyList; res.header.push_back( "itemTypeID" ); res.header.push_back( "quantity" ); res.header.push_back( "inCrate" ); std::map<uint32, ContractRequestItemRef>::const_iterator rCur, rEnd; for(; rCur != rEnd; rCur++ ) { fieldData->AddItemInt( rCur->second->m_typeID ); fieldData->AddItemInt( rCur->second->m_quantity ); fieldData->AddItemInt( false ); res.lines->AddItem( fieldData ); fieldData = new PyList; } std::map<uint32, ContractGetItemsRef>::const_iterator iCur, iEnd; for(; iCur != iEnd; iCur++ ) { fieldData->AddItemInt( iCur->second->m_itemID ); fieldData->AddItemInt( iCur->second->m_quantity ); fieldData->AddItemInt( true ); res.lines->AddItem( fieldData ); fieldData = new PyList; } } _contract->SetItemString( "contracts", rowset ); _contract->SetItemString( "items", res.Encode() ); _contract->SetItemString( "bids", new PyNone ); return new PyObject( new PyString( "util.KeyVal" ), _contract ); }
//this is a crap load of work... there HAS to be a better way to do this.. PyObject *MarketDB::GetMarketGroups() { DBQueryResult res; //returns cached object marketProxy.GetMarketGroups //marketGroupID, parentGroupID, marketGroupName, description, graphicID, hasTypes, types //this is going to be a real pain... another "nested" query thing... // I really wanna know how they do this crap with their MS SQL server.. // I hope its not as much of a nightmare as it is for us.... //first we need to query out all the types because we need them to // fill in the 'types' subquery for each row of the result std::map< int, std::set<uint32> > types; //maps marketGroupID -> typeID if(!sDatabase.RunQuery(res, "SELECT" " marketGroupID,typeID" " FROM invTypes" " WHERE marketGroupID IS NOT NULL" " ORDER BY marketGroupID")) { codelog(MARKET__ERROR, "Error in query: %s", res.error.c_str()); return NULL; } DBResultRow row; while(res.GetRow(row)) types[row.GetUInt(0)].insert(row.GetUInt(1)); if(!sDatabase.RunQuery(res, "SELECT" " marketGroupID, parentGroupID" " FROM invMarketGroups")) { codelog(MARKET__ERROR, "Error in query: %s", res.error.c_str()); return NULL; } std::map<int, int> parentChild; //maps child -> parent std::map<int, std::set<int> > childParent; //maps parent -> all children. while(res.GetRow(row)) { //figure out the parent ID, mapping NULL to -1 for our map. int marketGroupID = row.GetUInt(0); int parentGroupID = row.IsNull(1) ? -1 : row.GetUInt(1); parentChild[marketGroupID] = parentGroupID; childParent[parentGroupID].insert(marketGroupID); } //now we need to propigate all of the items up the tree (a parent group's items list contains ALL items of its children.) _PropigateItems(types, parentChild, childParent, -1); //now we get to do the other query. if(!sDatabase.RunQuery(res, "SELECT" " marketGroupID, parentGroupID, marketGroupName, description, graphicID, hasTypes" " FROM invMarketGroups")) { codelog(MARKET__ERROR, "Error in query: %s", res.error.c_str()); return NULL; } //doing this the long (non XML) way to avoid the extra copies due to the huge volume of data here. PyDict *args = new PyDict(); PyDict *parentSets = new PyDict(); PyList *header = new PyList(); header->AddItemString("marketGroupID"); header->AddItemString("parentGroupID"); header->AddItemString("marketGroupName"); header->AddItemString("description"); header->AddItemString("graphicID"); header->AddItemString("hasTypes"); header->AddItemString("types"); //this column really contains an entire list. header->AddItemString("dataID"); args->SetItemString("header", header); args->SetItemString("idName", new PyString("parentGroupID")); args->SetItemString("RowClass", new PyToken("util.Row")); args->SetItemString("idName2", new PyNone); args->SetItemString("items", parentSets); //now fill in items. // we have to satisfy this structure... which uses parentGroupID as the // main dict key, each dict entry is then a list of MarketGroup_Entrys // which have that parentGroupID //marketGroupID, parentGroupID, marketGroupName, description, graphicID, hasTypes, types std::map< int, std::set<uint32> >::const_iterator tt; MarketGroup_Entry entry; PyList* list; PyList* parents = new PyList(); while( res.GetRow(row) ) { entry.marketGroupID = row.GetUInt( 0 ); //figure out the parent ID, mapping NULL to -1 for our map. entry.parentGroupID = ( row.IsNull( 1 ) ? -1 : row.GetUInt( 1 ) ); entry.marketGroupName = row.GetText( 2 ); entry.description = row.GetText( 3 ); entry.graphicID = ( row.IsNull( 4 ) ? -1 : row.GetUInt( 4 ) ); entry.hasTypes = row.GetUInt( 5 ); // Insert all types entry.types.clear(); tt = types.find( entry.marketGroupID ); if( tt != types.end() ) entry.types.insert( entry.types.begin(), tt->second.begin(), tt->second.end() ); if(entry.parentGroupID == -1) list = parents; else list = static_cast<PyList*> (parentSets->GetItem(new PyInt( entry.parentGroupID ))); if(list == NULL) list = new PyList(); list->AddItem(entry.Encode()); PySafeIncRef(list); if(entry.parentGroupID != -1) parentSets->SetItem(new PyInt(entry.parentGroupID), list); } parentSets->SetItem(new PyNone, parents); return new PyObject( "util.FilterRowset", args ); }