Beispiel #1
0
PyDict *SimpleSystemEntity::MakeSlimItem() const {
	PyDict *slim = new PyDict();
	slim->SetItemString("typeID", new PyInt(data.typeID));
	slim->SetItemString("ownerID", new PyInt(1));
	slim->SetItemString("itemID", new PyInt(data.itemID));
	return slim;
}
PyDict *ItemSystemEntity::MakeSlimItem() const {
	PyDict *slim = new PyDict();
	slim->SetItemString("itemID", new PyInt(Item()->itemID()));
	slim->SetItemString("typeID", new PyInt(Item()->typeID()));
	slim->SetItemString("ownerID", new PyInt(Item()->ownerID()));
	return(slim);
}
Beispiel #3
0
PyObject *DBRowToRow(DBResultRow &row, const char *type)
{

    PyDict *args = new PyDict();
    PyObject *res = new PyObject( type, args );

    //list off the column names:
    uint32 cc = row.ColumnCount();
    PyList *header = new PyList(cc);
    args->SetItemString("header", header);

    for(uint32 r = 0; r < cc; r++) {
        header->SetItemString(r, row.ColumnName(r));
    }

    //lines:
    PyList *rowlist = new PyList(cc);
    args->SetItemString("line", rowlist);

    //add a line entry for the row:
    for(uint32 r = 0; r < cc; r++) {
        rowlist->SetItem(r, DBColumnToPyRep(row, r));
    }

    return res;
}
Beispiel #4
0
PyDict *SystemStationEntity::MakeSlimItem() const {
	PyDict *slim = new PyDict();
	slim->SetItemString("typeID", new PyInt(data.typeID));
	//HACKED:::
	slim->SetItemString("ownerID", new PyInt(1000044));
	slim->SetItemString("itemID", new PyInt(data.itemID));
	return(slim);
}
Beispiel #5
0
PyDict* UserError::_CreateKeywords( const char* msg )
{
    PyDict* keywords = new PyDict;
    keywords->SetItemString( "msg", new PyString( msg ) );
    keywords->SetItemString( "dict", new PyDict );

    return keywords;
}
Beispiel #6
0
//this is a crap load of work... there HAS to be a better way to do this..
PyRep *MarketDB::GetMarketGroups() {
    
    DBQueryResult res;
    DBResultRow row;

    if(!sDatabase.RunQuery(res,
        "SELECT * "
        " FROM invMarketGroups"))
    {
        codelog(MARKET__ERROR, "Error in query: %s", res.error.c_str());
        return NULL;
    }

	DBRowDescriptor *header = new DBRowDescriptor(res);
    
    CFilterRowSet *filterRowset = new CFilterRowSet(&header);
    
    PyDict *keywords = filterRowset->GetKeywords();
	keywords->SetItemString("giveMeSets", new PyBool(false)); //+
	keywords->SetItemString("allowDuplicateCompoundKeys", new PyBool(false)); //+
	keywords->SetItemString("indexName", new PyNone); //+
	keywords->SetItemString("columnName", new PyString("parentGroupID")); //+
    std::map< int, PyRep* > tt;

    while( res.GetRow(row) )
    {
        int parentGroupID = ( row.IsNull( 0 ) ? -1 : row.GetUInt( 0 ) );
        PyRep *pid;
        CRowSet *rowset;
        if(tt.count(parentGroupID) == 0) {
            pid = parentGroupID!=-1 ? (PyRep*)new PyInt(parentGroupID) : (PyRep*)new PyNone();
            tt.insert( std::pair<int, PyRep*>(parentGroupID, pid) );
            rowset = filterRowset->NewRowset(pid);
        } else {
            pid = tt[parentGroupID];
            rowset = filterRowset->GetRowset(pid);
        }
        
        PyPackedRow* pyrow = rowset->NewRow();

        pyrow->SetField((uint32)0, pid); //prentGroupID
        pyrow->SetField(1, new PyInt(row.GetUInt( 1 ) ) ); //marketGroupID
        pyrow->SetField(2, new PyString(row.GetText( 2 ) ) ); //marketGroupName
        pyrow->SetField(3, new PyString(row.GetText( 3 ) ) ); //description
        pyrow->SetField(4, row.IsNull( 4 ) ? 
            (PyRep*)(new PyNone()) : new PyInt(row.GetUInt( 4 ))  ); //graphicID
        pyrow->SetField(5, new PyBool(row.GetBool( 5 ) ) ); //hasTypes
        pyrow->SetField(6, row.IsNull( 6 ) ? 
            (PyRep*)(new PyNone()) : new PyInt(row.GetUInt( 6 ))  ); // iconID 
        pyrow->SetField(7, new PyInt( row.GetUInt(7) )  ); //dataID
        pyrow->SetField(8, new PyInt( row.GetUInt(8) )  ); //marketGroupNameID
        pyrow->SetField(9, new PyInt( row.GetUInt(9) )  ); //descriptionID
    }

    return filterRowset;
}
Beispiel #7
0
PyDict* CFilterRowSet::_CreateKeywords(DBRowDescriptor* rowDesc)
{
    assert( rowDesc );

    PyDict* keywords = new PyDict;
    keywords->SetItemString( "header", rowDesc );
    keywords->SetItemString( "columnName", rowDesc->GetColumnName(0) );


    return keywords;
}
PyRep* FactionWarMgrDB::GetFacWarSystems()
{
    sLog.Debug( "FactionWarMgrDB", "Called GetFacWarSystems stub." );

	//fill some crap
	PyDict* result = new PyDict;
	PyDict* dict;

	dict = new PyDict;
	dict->SetItemString( "occupierID", new PyInt( 500002 ) );
	dict->SetItemString( "factionID", new PyInt( 500002 ) );
	result->SetItem( new PyInt( 30002097 ), dict );

	return result;
}
Beispiel #9
0
PyDict* CRowSet::_CreateKeywords(DBRowDescriptor* rowDesc)
{
	assert( rowDesc );

	PyDict* keywords = new PyDict;
	keywords->SetItemString( "header", rowDesc );

	uint32 cc = rowDesc->ColumnCount();
	PyList* columns = new PyList( cc );
	for( uint32 i = 0; i < cc; i++ )
		columns->SetItem( i,  new PyString( *rowDesc->GetColumnName( i ) ) );
	keywords->SetItemString( "columns", columns );

	return keywords;
}
Beispiel #10
0
PyDict *SystemStargateEntity::MakeSlimItem() const {
	PyDict *slim = SystemStationEntity::MakeSlimItem();
    if(m_jumps != NULL) {
        PyIncRef(m_jumps);
		slim->SetItemString("jumps", m_jumps);
    }
	return slim;
}
Beispiel #11
0
PyObject *DBRowToKeyVal(DBResultRow &row) {

    PyDict *args = new PyDict();
    PyObject *res = new PyObject( "util.KeyVal", args );

    uint32 cc = row.ColumnCount();
    for( uint32 r = 0; r < cc; r++ )
        args->SetItemString( row.ColumnName(r), DBColumnToPyRep(row, r));

    return res;
}
Beispiel #12
0
PyObject *DBResultToIndexRowset(DBQueryResult &result, uint32 key_index) {
    uint32 cc = result.ColumnCount();

    //start building the IndexRowset
    PyDict *args = new PyDict();
    PyObject *res = new PyObject(
        new PyString( "util.IndexRowset" ), args
    );

    if(cc == 0 || cc < key_index)
        return res;
    
    //list off the column names:
    PyList *header = new PyList(cc);
    args->SetItemString("header", header);
    for(uint32 i = 0; i < cc; i++)
        header->SetItemString(i, result.ColumnName(i));

    //RowClass:
    args->SetItemString("RowClass", new PyToken("util.Row"));
    //idName:
    args->SetItemString("idName", new PyString( result.ColumnName(key_index) ));

    //items:
    PyDict *items = new PyDict();
    args->SetItemString("items", items);

    //add a line entry for each result row:
    DBResultRow row;
    while(result.GetRow(row)) {
        PyRep *key = DBColumnToPyRep(row, key_index);

        PyList *line = new PyList(cc);
        for(uint32 i = 0; i < cc; i++)
            line->SetItem(i, DBColumnToPyRep(row, i));

        items->SetItem(key, line);
    }

    return res;
}
Beispiel #13
0
PyObject *DBResultToRowset(DBQueryResult &result)
{
    uint32 r;
    uint32 cc = result.ColumnCount();

    PyDict *args = new PyDict();
    PyObject *res = new PyObject(
        new PyString( "util.Rowset" ), args
    );

    /* check if we have a empty query result and return a empty RowSet */
    if( cc == 0 )
        return res;

    //list off the column names:
    PyList *header = new PyList( cc );
    args->SetItemString("header", header);
    for(r = 0; r < cc; r++) {
        header->SetItemString( r, result.ColumnName(r));
    }

    //RowClass:
    args->SetItemString("RowClass", new PyToken("util.Row"));

    //lines:
    PyList *rowlist = new PyList();
    args->SetItemString("lines", rowlist);

    //add a line entry for each result row:
    DBResultRow row;
    while(result.GetRow(row)) {
        PyList *linedata = new PyList( cc );
        rowlist->AddItem(linedata);

        for(r = 0; r < cc; r++) {
            linedata->SetItem( r, DBColumnToPyRep(row, r) );
        }
    }

    return res;
}
Beispiel #14
0
PyResult BulkMgrService::Handle_UpdateBulk(PyCallArgs &call)
{
    Call_UpdateBulk args;
    if(!args.Decode(&call.tuple)) {
        codelog(CLIENT__ERROR, "Invalid arguments");
	return NULL;
    }

    PyDict* test = new PyDict();
    test->SetItemString("type", new PyInt(updateBulkStatusOK));
    test->SetItemString("allowUnsubmitted", new PyBool(false));

    return test;
}
PyResult MailMgrService::Handle_SyncMail(PyCallArgs &call)
{
    int firstId = 0, secondId = 0;

    if (call.tuple->size() == 2 && !call.tuple->GetItem(0)->IsNone() && !call.tuple->GetItem(1)->IsNone())
    {
        Call_TwoIntegerArgs args;
        if (!args.Decode(&call.tuple))
        {
            codelog(CLIENT__ERROR, "Failed to decode SyncMail args");
            return NULL;
        }

        // referring to a mail id range
        int firstId = args.arg1, secondId = args.arg2;
    }

    PyDict* dummy = new PyDict;
    dummy->SetItemString("oldMail", new PyNone());
    dummy->SetItemString("newMail", m_db->GetNewMail(call.client->GetCharacterID()));
    dummy->SetItemString("mailStatus", m_db->GetMailStatus(call.client->GetCharacterID()));
    return new PyObject("util.KeyVal", dummy);
}
PyResult ContractMgrService::Handle_NumRequiringAttention( PyCallArgs& call )
{
	uint32 requiresAttentionCorp = 0;
	uint32 requiresAttention = 0;

	std::map<uint32, ContractRef>::const_iterator cur, end;
	std::map<uint32, ContractRef> contracts = m_contractManager->GetContractList();

	cur = contracts.begin();
	end = contracts.end();

	for(; cur != end; cur++ )
	{
		ContractRef contract = cur->second;
		if( contract->requiresAttention() )
		{
			if( contract->issuerCorpID() == call.client->GetCorporationID() )
			{
				requiresAttentionCorp += 1;
			}else if( contract->issuerID() == call.client->GetCharacterID() ){
				requiresAttention += 1;
			}else if( contract->acceptorID() == call.client->GetCharacterID() ){
				requiresAttention += 1;
			}else if( contract->assigneeID() == call.client->GetCharacterID() ){
				requiresAttention += 1;
			}
		}
	}

	PyDict* args = new PyDict;
	args->SetItemString( "n", new PyInt( requiresAttention ) );
	args->SetItemString( "ncorp", new PyInt( requiresAttentionCorp ) );

	return new PyObject(
        new PyString( "util.KeyVal" ), args
    );
}
Beispiel #17
0
PyDict* CRowSet::_CreateKeywords(DBRowDescriptor* rowDesc)
{
    assert( rowDesc );

    PyDict* keywords = new PyDict;
    keywords->SetItemString( "header", rowDesc );

    //uint32 cc = rowDesc->ColumnCount();
    //PyList* columns = new PyList( cc );
    //for( uint32 i = 0; i < cc; i++ )
    //    columns->SetItem( i,  new PyString( *rowDesc->GetColumnName( i ) ) );
    //keywords->SetItemString( "columns", columns ); //The Type_2 i had no longer used this

    return keywords;
}
Beispiel #18
0
PyDict* GPSTransportClosed::_CreateKeywords( const char* reason )
{
    PyDict* keywords = new PyDict;
    //keywords->SetItemString( "origin", new PyString( "proxy" ) );
    keywords->SetItemString( "reasonArgs", new PyDict );
    keywords->SetItemString( "clock", new PyLong( Win32TimeNow() ) );
    //keywords->SetItemString( "loggedOnUserCount", );
    keywords->SetItemString( "region", new PyString( EVEProjectRegion ) );
    keywords->SetItemString( "reason", new PyString( reason ) );
    keywords->SetItemString( "version", new PyFloat( EVEVersionNumber ) );
    keywords->SetItemString( "build", new PyInt( EVEBuildVersion ) );
    //keywords->SetItemString( "reasonCode", );
    keywords->SetItemString( "codename", new PyString( EVEProjectCodename ) );
    keywords->SetItemString( "machoVersion", new PyInt( MachoNetVersion ) );

    return keywords;
}
Beispiel #19
0
PyResult InfoGatheringService::Handle_GetStateAndConfig(PyCallArgs &call) {

	sLog.Debug("Server", "Called GetStateAndConfig");

	PyDict* args = new PyDict;
	
	args->SetItemString( "clientWorkerInterval", new PyInt( 0 ) );
	args->SetItemString( "isEnabled", new PyInt( 0 ) );
	args->SetItemString( "infoTypeAggregates", new PyDict );
	args->SetItemString( "infoTypesOncePerRun", new PyDict );
	args->SetItemString( "infoTypeParameters", new PyDict );
	args->SetItemString( "infoTypes", new PyDict );

	return new PyObject( "util.KeyVal", args );
}
Beispiel #20
0
PyResult InfoGatheringMgr::Handle_GetStateAndConfig(PyCallArgs &call) {
	
	PyDict *rsp = new PyDict;
	
	rsp->SetItemString("clientWorkerInterval", new PyInt(600000)); //Default From packetlogs is 600000
	rsp->SetItemString("isEnabled", new PyInt(0)); //0 = Disabled, 1 = Enabled. Set to 0 becuase jsut gettting rid of exception.

	rsp->SetItemString("infoTypeAggregates", new PyNone());
	rsp->SetItemString("infoTypesOncePerRun", new PyNone());
	rsp->SetItemString("infoTypeParameters", new PyNone());

	PyList *infoTypes = new PyList;
	infoTypes->AddItemInt(999); //Adding a value that was not in live so when its checks list it will always return false for now.
	
	rsp->SetItemString("infoTypes", new PyObjectEx_Type1( new PyToken("__builtin__.set"), new_tuple(infoTypes)));
	
	return new PyObject( "util.KeyVal", rsp );
}
Beispiel #21
0
PyDict *SystemStargateEntity::MakeSlimItem() const {
    PyDict *slim = SystemStationEntity::MakeSlimItem();
    if(m_jumps != NULL)
        slim->SetItemString("jumps", m_jumps->Clone());
    return(slim);
}
PyResult ContractMgrService::Handle_CollectMyPageInfo( PyCallArgs& call )
{
	PyDict* ret = new PyDict;
	uint32 numOutstandingContractsNonCorp = 0;
	uint32 numOutstandingContractsForCorp = 0;
	uint32 numContractsLeft = 0;
	uint32 numRequiresAttention = 0;
	uint32 numRequiresAttentionCorp = 0;
	uint32 numAssignedTo = 0;
	uint32 numAssignedToCorp = 0;
	uint32 numBiddingOn = 0;
	uint32 numInProgress = 0;
	uint32 numBiddingOnCorp = 0;
	uint32 numInProgressCorp = 0;

	std::map<uint32, ContractRef>::const_iterator cur, end;
	std::map<uint32, ContractRef> contracts = m_contractManager->GetContractList();

	cur = contracts.begin();
	end = contracts.end();

	for(; cur != end; cur++ )
	{
		ContractRef contract = cur->second;
		if( contract->issuerID() == call.client->GetCharacterID() )
		{
			if( contract->forCorp() == true )
			{
				if( contract->requiresAttention() ) numRequiresAttentionCorp += 1;
				if( contract->assigneeID() ) numAssignedToCorp += 1;
				if( contract->status() == conStatusInProgress ) numInProgressCorp += 1;
				numOutstandingContractsForCorp += 1;
			}else{
				if( contract->requiresAttention() ) numRequiresAttention += 1;
				if( contract->assigneeID() ) numAssignedTo += 1;
				if( contract->status() == conStatusInProgress ) numInProgress += 1;
				numOutstandingContractsNonCorp += 1;
			}

		}
	}

	ret->SetItemString( "numOutstandingContractsNonCorp", new PyInt( numOutstandingContractsNonCorp ) );
	ret->SetItemString( "numOutstandingContractsForCorp", new PyInt( numOutstandingContractsForCorp ) );
	ret->SetItemString( "numOutstandingContracts", new PyInt( numOutstandingContractsNonCorp + numOutstandingContractsForCorp ) );
	ret->SetItemString( "numContractsLeft", new PyInt( numContractsLeft ) );
	ret->SetItemString( "numRequiresAttention", new PyInt( numRequiresAttention ) );
	ret->SetItemString( "numRequiresAttentionCorp", new PyInt( numRequiresAttentionCorp ) );
	ret->SetItemString( "numAssignedTo", new PyInt( numAssignedTo ) );
	ret->SetItemString( "numAssignedToCorp", new PyInt( numAssignedToCorp ) );
	ret->SetItemString( "numBiddingOn", new PyInt( numBiddingOn ) );
	ret->SetItemString( "numInProgress", new PyInt( numInProgress ) );
	ret->SetItemString( "numBiddingOnCorp", new PyInt( numBiddingOnCorp ) );
	ret->SetItemString( "numInProgressCorp", new PyInt( numInProgressCorp ) );
	
	return new PyObject(
		new PyString( "util.KeyVal" ), ret 
		);
}
Beispiel #23
0
//this is a big hack just to document the kind of stuff a dungeon conveys.
PyDict *SystemDungeonEntranceEntity::MakeSlimItem() const {
	
	PyDict *slim = ItemSystemEntity::MakeSlimItem();
	if(slim == NULL)
		return NULL;
	
	//slim->SetItemString("itemID", new PyInt(2100000396));
	//slim->SetItemString("typeID", new PyInt(12273));
	//slim->SetItemString("ownerID", new PyInt(500021));
	
	slim->SetItemString("dunSkillLevel", new PyInt(0));
	slim->SetItemString("dunSkillTypeID", new PyNone);
	slim->SetItemString("dunObjectID", new PyInt(160449));
	slim->SetItemString("dunWipeNPC", new PyInt(1));
	slim->SetItemString("dunToGateID", new PyInt(160484));
	slim->SetItemString("dunCloaked", new PyInt(0));
	slim->SetItemString("dunScenarioID", new PyInt(23));
	slim->SetItemString("dunSpawnID", new PyInt(4));
	slim->SetItemString("dunAmount", new PyFloat(0.0));
	slim->SetItemString("dunShipClasses", new PyList(/*237, 31*/));
	slim->SetItemString("dunDirection", new PyList(/*235, 0, 1*/));
	slim->SetItemString("dunKeyLock", new PyInt(0));
	//slim->SetItemString("dunKeyQuantity", new PyInt(1));
	//slim->SetItemString("dunKeyTypeID", new PyInt(21839));
	//slim->SetItemString("dunOpenUntil", new PyInt(Win32TimeNow()+Win32Time_Hour));
	slim->SetItemString("dunMusicUrl", new PyString("res:/Sound/Music/Ambient031combat.ogg"));
	
	return(slim);
}
Beispiel #24
0
PyRep *MarketDB::CollectMyPageInfo( uint32 clientID )
{
	DBQueryResult res;
	DBResultRow row;
	if(!sDatabase.RunQuery(res,
		"SELECT numOutstandingContractsNonCorp,"
		" numOutstandingContractsForCorp,"
		" numOutstandingContracts,"
		" numContractsLeft,"
		" numRequiresAttention,"
		" numRequiresAttentionCorp,"
		" numAssignedTo,"
		" numAssignedToCorp,"
		" numBiddingOn,"
		" numInProgress,"
		" numBiddingOnCorp,"
		" numInProgressCorp"
		" FROM chrcontractinfo"
		" WHERE characterID=%d", clientID))
	{
		codelog( MARKET__ERROR, "Error in query: %s", res.error.c_str() );
		return NULL;
	}

	if(!res.GetRow(row)) {
		codelog(MARKET__ERROR, "Player %u chrcontractinfo not found.", clientID);
		return NULL;
	}

	PyDict* PageInfo = new PyDict;
	PageInfo->SetItemString( "numOutstandingContractsNonCorp", new PyInt( row.GetInt( 0 ) ) );
	PageInfo->SetItemString( "numOutstandingContractsForCorp", new PyInt( row.GetInt( 1 ) ) );
	PageInfo->SetItemString( "numOutstandingContracts", new PyInt( row.GetInt( 2 ) ) );
	PageInfo->SetItemString( "numContractsLeft", new PyInt( row.GetInt( 3 ) ) );
	PageInfo->SetItemString( "numRequiresAttention", new PyInt( row.GetInt( 4 ) ) );
	PageInfo->SetItemString( "numRequiresAttentionCorp", new PyInt( row.GetInt( 5 ) ) );
	PageInfo->SetItemString( "numAssignedTo", new PyInt( row.GetInt( 6 ) ) );
	PageInfo->SetItemString( "numAssignedToCorp", new PyInt( row.GetInt( 7 ) ) );
	PageInfo->SetItemString( "numBiddingOn", new PyInt( row.GetInt( 8 ) ) );
	PageInfo->SetItemString( "numInProgress", new PyInt( row.GetInt( 9 ) ) );
	PageInfo->SetItemString( "numBiddingOnCorp", new PyInt( row.GetInt( 10 ) ) );
	PageInfo->SetItemString( "numInProgressCorp", new PyInt( row.GetInt( 11 ) ) );
	return PageInfo;
}
Beispiel #25
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 );
}