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
		);
}
Example #2
0
//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 );
}