function getSearchResultAsRecordSet( $queryResult ) {

	$o = OmegaWikiAttributes::getInstance();
	global
		$definedMeaningReferenceType,
		$wgDefinedMeaning;

	$dbr = wfGetDB( DB_SLAVE );
	$spellingAttribute = new Attribute( "found-word", "Found word", "short-text" );
	$languageAttribute = new Attribute( "language", "Language", "language" );
	
	$expressionStructure = new Structure( $spellingAttribute, $languageAttribute );
	$expressionAttribute = new Attribute( "expression", "Expression", $expressionStructure );
	
	$definedMeaningAttribute = new Attribute( $wgDefinedMeaning, "Defined meaning", $definedMeaningReferenceType );
	$definitionAttribute = new Attribute( "definition", "Definition", "definition" );
	
	$meaningStructure = new Structure( $definedMeaningAttribute, $definitionAttribute );
	$meaningAttribute = new Attribute( "meaning", "Meaning", $meaningStructure );

	$recordSet = new ArrayRecordSet( new Structure( $o->definedMeaningId, $expressionAttribute, $meaningAttribute ), new Structure( $o->definedMeaningId ) );
	
	while ( $row = $dbr->fetchObject( $queryResult ) ) {
		$expressionRecord = new ArrayRecord( $expressionStructure );
		$expressionRecord->setAttributeValue( $spellingAttribute, $row->spelling );
		$expressionRecord->setAttributeValue( $languageAttribute, $row->language_id );
		
		$meaningRecord = new ArrayRecord( $meaningStructure );
		$meaningRecord->setAttributeValue( $definedMeaningAttribute, getDefinedMeaningReferenceRecord( $row->defined_meaning_id ) );
		$meaningRecord->setAttributeValue( $definitionAttribute, getDefinedMeaningDefinition( $row->defined_meaning_id ) );

		$recordSet->addRecord( array( $row->defined_meaning_id, $expressionRecord, $meaningRecord ) );
	}

	$expressionEditor = new RecordTableCellEditor( $expressionAttribute );
	$expressionEditor->addEditor( new SpellingEditor( $spellingAttribute, new SimplePermissionController( false ), false ) );
	$expressionEditor->addEditor( new LanguageEditor( $languageAttribute, new SimplePermissionController( false ), false ) );

	$meaningEditor = new RecordTableCellEditor( $meaningAttribute );
	$meaningEditor->addEditor( new DefinedMeaningReferenceEditor( $definedMeaningAttribute, new SimplePermissionController( false ), false ) );
	$meaningEditor->addEditor( new TextEditor( $definitionAttribute, new SimplePermissionController( false ), false, true, 75 ) );

	$editor = createTableViewer( null );
	$editor->addEditor( $expressionEditor );
	$editor->addEditor( $meaningEditor );

	return array( $recordSet, $editor );
}
	private function getTransactionAsRecordSet( $queryResult ) {

		$o = OmegaWikiAttributes::getInstance();

		$dbr = wfGetDB( DB_SLAVE );

		$userAttribute = new Attribute( "user", wfMsg( 'ow_User' ), "short-text" );
		$timestampAttribute = new Attribute( "timestamp", wfMsg( 'ow_Time' ), "timestamp" );
		$summaryAttribute = new Attribute( "summary", wfMsg( 'ow_transaction_summary' ), "short-text" );

		$recordSet = new ArrayRecordSet( new Structure( $o->id, $userAttribute, $timestampAttribute, $summaryAttribute ), new Structure( $o->id ) );

		while ( $row = $dbr->fetchObject( $queryResult ) )
			$recordSet->addRecord( array( $row->transaction_id, getUserLabel( $row->user_id, $row->user_ip ), $row->time, $row->comment ) );

		$editor = createSuggestionsTableViewer( null );
		$editor->addEditor( createShortTextViewer( $timestampAttribute ) );
		$editor->addEditor( createShortTextViewer( $o->id ) );
		$editor->addEditor( createShortTextViewer( $userAttribute ) );
		$editor->addEditor( createShortTextViewer( $summaryAttribute ) );

		return array( $recordSet, $editor );
	}
function queryRecordSet( $recordSetStructureId, QueryTransactionInformation $transactionInformation, Attribute $keyAttribute, TableColumnsToAttributesMapping $tableColumnsToAttributeMapping, Table $table, array $restrictions, array $orderBy = array(), $count = - 1, $offset = 0 ) {
	$dbr = wfGetDB( DB_SLAVE );
	
	$selectFields =  $tableColumnsToAttributeMapping->getSelectColumns();
	$attributes = $tableColumnsToAttributeMapping->getAttributes();

	if ( $table->isVersioned ) {
		$allAttributes = array_merge( $attributes, $transactionInformation->versioningAttributes() );
	} else {
		$allAttributes = $attributes;
	}
	
	$query = getTransactedSQL( $transactionInformation, $selectFields, $table, $restrictions, $orderBy, $count, $offset );
	$queryResult = $dbr->query( $query );
	
	if ( !is_null( $recordSetStructureId ) ) {
		$structure = new Structure( $recordSetStructureId, $allAttributes );
	} else {
		$structure = new Structure( $allAttributes );
	}

	$recordSet = new ArrayRecordSet( $structure, new Structure( $keyAttribute ) );

	while ( $row = $dbr->fetchRow( $queryResult ) ) {
		$record = new ArrayRecord( $structure );
		$columnIndex = 0;

		for ( $i = 0; $i < $tableColumnsToAttributeMapping->getCount(); $i++ ) {
			$mapping = $tableColumnsToAttributeMapping->getMapping( $i );
			$attribute = $mapping->getAttribute();
			$tableColumns = $mapping->getTableColumns();
			
			if ( count( $tableColumns ) == 1 ) {
				$value = $row[$columnIndex];
			} else {
				$value = getRecordFromRow( $row, $columnIndex, $attribute->type );
			}
			
			$record->setAttributeValue( $attribute, $value );
			$columnIndex += count( $tableColumns );
		}
			
		$transactionInformation->setVersioningAttributes( $record, $row );
		$recordSet->add( $record );
	}
		
	return $recordSet;
}
function splitRecordSet( $recordSet, $groupAttribute ) {
	$result = array();
	$structure = $recordSet->getStructure();
	$key = $recordSet->getKey();
	
	for ( $i = 0; $i < $recordSet->getRecordCount(); $i++ ) {
		$record = $recordSet->getRecord( $i );
		$groupAttributeValue = $record->getAttributeValue( $groupAttribute );
		@$groupRecordSet = $result[$groupAttributeValue]; # FIXME - check existence in array

		if ( $groupRecordSet == null ) {
			$groupRecordSet = new ArrayRecordSet( $structure, $key );
			$result[$groupAttributeValue] = $groupRecordSet;
		}
		
		$groupRecordSet->add( $record );
	}
	
	return $result;
}
	protected function showExpressionsNeedingTranslation( $sourceLanguageId, $destinationLanguageId, $collectionId ) {

		$o = OmegaWikiAttributes::getInstance();

		$dc = wdGetDataSetContext();
		require_once( "Transaction.php" );
		require_once( "OmegaWikiAttributes.php" );
		require_once( "RecordSet.php" );
		require_once( "Editor.php" );
		require_once( "WikiDataAPI.php" );

		$dbr = wfGetDB( DB_SLAVE );

		$sqlcount = 'SELECT COUNT(*)' .
			" FROM ({$dc}_syntrans source_syntrans, {$dc}_expression source_expression)";

		if ( $collectionId != '' )
			$sqlcount .= " JOIN {$dc}_collection_contents ON source_syntrans.defined_meaning_id = member_mid";

		$sqlcount .= ' WHERE source_syntrans.expression_id = source_expression.expression_id';

		if ( $sourceLanguageId != '' )
			$sqlcount .= ' AND source_expression.language_id = ' . $sourceLanguageId;
		if ( $collectionId != '' )
			$sqlcount .= " AND {$dc}_collection_contents.collection_id = " . $collectionId .
				' AND ' . getLatestTransactionRestriction( "{$dc}_collection_contents" );

		$sqlcount .= ' AND NOT EXISTS (' .
			" SELECT * FROM {$dc}_syntrans destination_syntrans, {$dc}_expression destination_expression" .
			' WHERE destination_syntrans.expression_id = destination_expression.expression_id AND destination_expression.language_id = ' . $destinationLanguageId .
			' AND source_syntrans.defined_meaning_id = destination_syntrans.defined_meaning_id' .
			' AND ' . getLatestTransactionRestriction( 'destination_syntrans' ) .
			' AND ' . getLatestTransactionRestriction( 'destination_expression' ) .
			')' .
			' AND ' . getLatestTransactionRestriction( 'source_syntrans' ) .
			' AND ' . getLatestTransactionRestriction( 'source_expression' ) ;

		$queryResultCount_r = mysql_query( $sqlcount );
		$queryResultCount_a = mysql_fetch_row( $queryResultCount_r );
		$queryResultCount = $queryResultCount_a[0];
		$nbshown = min ( 100, $queryResultCount ) ;


		$sql = 'SELECT source_expression.expression_id AS source_expression_id, source_expression.language_id AS source_language_id, source_expression.spelling AS source_spelling, source_syntrans.defined_meaning_id AS source_defined_meaning_id' .
			" FROM ({$dc}_syntrans source_syntrans, {$dc}_expression source_expression)";

		if ( $collectionId != '' )
			$sql .= " JOIN {$dc}_collection_contents ON source_syntrans.defined_meaning_id = member_mid";

		$sql .= ' WHERE source_syntrans.expression_id = source_expression.expression_id';

		if ( $sourceLanguageId != '' )
			$sql .= ' AND source_expression.language_id = ' . $sourceLanguageId;
		if ( $collectionId != '' )
			$sql .= " AND {$dc}_collection_contents.collection_id = " . $collectionId .
				' AND ' . getLatestTransactionRestriction( "{$dc}_collection_contents" );

		$sql .= ' AND NOT EXISTS (' .
			" SELECT * FROM {$dc}_syntrans destination_syntrans, {$dc}_expression destination_expression" .
			' WHERE destination_syntrans.expression_id = destination_expression.expression_id AND destination_expression.language_id = ' . $destinationLanguageId .
			' AND source_syntrans.defined_meaning_id = destination_syntrans.defined_meaning_id' .
			' AND ' . getLatestTransactionRestriction( 'destination_syntrans' ) .
			' AND ' . getLatestTransactionRestriction( 'destination_expression' ) .
			')' .
			' AND ' . getLatestTransactionRestriction( 'source_syntrans' ) .
			' AND ' . getLatestTransactionRestriction( 'source_expression' ) ;

		if ( $queryResultCount > 100 ) {
			$startnumber = rand ( 0 , $queryResultCount - 100 ) ;
			$sql .= " LIMIT $startnumber,100";
		} else {
			$sql .= ' LIMIT 100';
		}

		$queryResult = $dbr->query( $sql );


		$definitionAttribute = new Attribute( "definition", wfMsg( "ow_Definition" ), "definition" );

		$recordSet = new ArrayRecordSet( new Structure( $o->definedMeaningId, $o->expressionId, $o->expression, $definitionAttribute ), new Structure( $o->definedMeaningId, $o->expressionId ) );

		while ( $row = $dbr->fetchObject( $queryResult ) ) {
			$expressionRecord = new ArrayRecord( $o->expressionStructure );
			$expressionRecord->language = $row->source_language_id;
			$spellingAsLink = definedMeaningReferenceAsLink( $row->source_defined_meaning_id, $row->source_spelling, $row->source_spelling );
			$expressionRecord->spelling = $spellingAsLink ;

			$definition = getDefinedMeaningDefinitionForLanguage( $row->source_defined_meaning_id, $row->source_language_id ) ;
			if ( $definition == "" ) {
				$definition = getDefinedMeaningDefinition( $row->source_defined_meaning_id ) ;
			}

			$recordSet->addRecord( array( $row->source_defined_meaning_id, $row->source_expression_id, $expressionRecord, $definition ) );
		}

		$expressionEditor = new RecordTableCellEditor( $o->expression );
		$expressionEditor->addEditor( new LanguageEditor( $o->language, new SimplePermissionController( false ), false ) );
		$expressionEditor->addEditor( new ShortTextNoEscapeEditor( $o->spelling, new SimplePermissionController( false ), false ) );

		$editor = new RecordSetTableEditor( null, new SimplePermissionController( false ), new ShowEditFieldChecker( true ), new AllowAddController( false ), false, false, null );
		$editor->addEditor( $expressionEditor );
		$editor->addEditor( new TextEditor( $definitionAttribute, new SimplePermissionController( false ), false, true, 75 ) );

		global $wgOut;

		$wgOut->addHTML( "Showing $nbshown out of $queryResultCount" ) ;
		$wgOut->addHTML( $editor->view( new IdStack( "expression" ), $recordSet ) );
	}
 function getExternalIdentifiersSearchResultAsRecordSet($queryResult)
 {
     $dbr = wfGetDB(DB_SLAVE);
     $externalIdentifierMatchStructure = new Structure($this->externalIdentifierAttribute, $this->collectionAttribute, $this->collectionMemberAttribute);
     $recordSet = new ArrayRecordSet($externalIdentifierMatchStructure, new Structure($this->externalIdentifierAttribute));
     while ($row = $dbr->fetchObject($queryResult)) {
         $record = new ArrayRecord($this->externalIdentifierMatchStructure);
         $record->setAttributeValue($this->externalIdentifierAttribute, $row->external_identifier);
         $record->setAttributeValue($this->collectionAttribute, $row->collection_mid);
         $record->setAttributeValue($this->collectionMemberAttribute, $row->member_mid);
         $recordSet->add($record);
     }
     expandDefinedMeaningReferencesInRecordSet($recordSet, array($this->collectionAttribute, $this->collectionMemberAttribute));
     return $recordSet;
 }
function getUpdatedTranslatedTextRecordSet( $transactionId ) {

	$o = OmegaWikiAttributes::getInstance();

	$dc = wdGetDataSetContext();
	$dbr = wfGetDB( DB_SLAVE );
	$queryResult = $dbr->query(
		"SELECT value_id, object_id, attribute_mid, translated_content_id, language_id, text_text, " .
			getOperationSelectColumn( "{$dc}_translated_content", $transactionId ) . ', ' .
			getIsLatestSelectColumn( "{$dc}_translated_content", array( 'translated_content_id', 'language_id' ), $transactionId ) .
		" FROM {$dc}_translated_content_attribute_values, {$dc}_translated_content, {$dc}_text " .
		" WHERE {$dc}_translated_content_attribute_values.value_tcid={$dc}_translated_content.translated_content_id " .
		" AND {$dc}_translated_content.text_id={$dc}_text.text_id " .
		" AND " . getInTransactionRestriction( "{$dc}_translated_content", $transactionId ) .
		" AND " . getAtTransactionRestriction( "{$dc}_translated_content_attribute_values", $transactionId )
	);
		
	$recordSet = new ArrayRecordSet( $o->updatedTranslatedTextStructure, new Structure( $o->valueId, $o->language ) );
	
	while ( $row = $dbr->fetchObject( $queryResult ) ) {
		$record = new ArrayRecord( $o->updatedTranslatedTextStructure );
		$record->valueId = $row->value_id;
		$record->objectId = $row->object_id;
		$record->attribute = getDefinedMeaningReferenceRecord( $row->attribute_mid );
		$record->translatedContentId = $row->translated_content_id;
		$record->language = $row->language_id;
		$record->text = $row->text_text;
		$record->operation = $row->operation;
		$record->isLatest = $row->is_latest;
		$record->rollBackTranslatedContent = simpleRecord( $o->rollBackTranslatedContentStructure, array( $row->is_latest, $row->operation, getTranslatedContentHistory( $row->translated_content_id, $row->language_id, $row->is_latest ) ) );
		$recordSet->add( $record );
	}
	
	return $recordSet;
}
function filterAttributeValues( RecordSet $sourceRecordSet, Attribute $attributeAttribute, array &$attributeIds ) {
	$result = new ArrayRecordSet( $sourceRecordSet->getStructure(), $sourceRecordSet->getKey() );
	$i = 0;
	
	while ( $i < $sourceRecordSet->getRecordCount() ) {
		$record = $sourceRecordSet->getRecord( $i );
		
		if ( in_array( $record->getAttributeValue( $attributeAttribute )->definedMeaningId, $attributeIds ) ) {
			$result->add( $record );
			$sourceRecordSet->remove( $i );
		}
		else
			$i++;
	}
	
	return $result;
}
	public function getAddValues( IdStack $idPath ) {
		$addStructure = $this->getAddStructure();

		if ( count( $addStructure->getAttributes() ) > 0 ) {
			$relations = array();

			$value_array_array = array(array());

			foreach ( $this->getEditors() as $editor ) {
				if ( $attribute = $editor->getAddAttribute() ) {
					$idPath->pushAttribute( $attribute );

					$addValues = $editor->getAddValues( $idPath );
					$i = 0;
					foreach ( $addValues as $value ) {
						$value_array_array[$i][] = $value ;
						$i++;
					}

					$idPath->popAttribute();
				}
			}

			foreach ( $value_array_array as $value_array ) {
				$relation = new ArrayRecordSet( $addStructure, $addStructure ) ;  // TODO Determine real key
				$relation->addRecord( $value_array );
				$relations[] = $relation ;
			}

			return $relations ;
		}
		else
			return null;
	}