/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.    
 */
#include "apache/das/rdb/PKObject.h"
#include "apache/das/rdb/ColumnData.h"

namespace apache {
	namespace das {
		namespace rdb {

PKObject::PKObject(const Table& table) {
	this->table = &table;
	primaryKeys = new KeyDataList();
	
}

PKObject::~PKObject(void) {
	KeyDataList::const_iterator it;
	
	for (it = primaryKeys->begin() ; it != primaryKeys->end() ; it++) {
		delete it->second;
	}

	delete primaryKeys;

}

void PKObject::addPrimaryKey(std::string columnName, ColumnData& columnData) {
	primaryKeys->insert(std::make_pair(columnName, &columnData));
}

const Table& PKObject::getTable(void) const {
	return *table;
}

bool PKObject::isPK(std::string columnName) const {
	KeyDataList::const_iterator it = primaryKeys->find(columnName);

	return it != primaryKeys->end();
	
}

bool PKObject::operator==(const KeyDataList* primaryKeyList) const {
	
	if (primaryKeys->size() != primaryKeyList->size()) {
		return false;
	}

	KeyDataList::const_iterator it, primaryKeyIterator;
	
	for (it = primaryKeyList->begin() ; it != primaryKeyList->end() ; it++) {
		primaryKeyIterator = primaryKeys->find(it->first);

		if (primaryKeyIterator == primaryKeys->end())  {
			return false;

		} else if (*it->second != *primaryKeyIterator->second) {
			return false;

		}

	}

	return true;
	
}

bool PKObject::operator==(const PKObject& pkObject) const {
	return (*this == pkObject.primaryKeys);
}

bool PKObject::operator!=(const PKObject& pkObject) const {
	return !(*this == pkObject);
}

bool PKObject::operator!=(const KeyDataList* primaryKeyList) const {
	return !(*this == primaryKeyList);
}

const KeyDataList& PKObject::getPrimaryKeys(void) const {
	return *primaryKeys;
}

bool PKObject::operator<(const PKObject& pkObject) const {
	return (*this < pkObject.primaryKeys);
}

bool PKObject::operator<(const KeyDataList* primaryKeyList) const {
	
	if (primaryKeys->size() < primaryKeyList->size()) {
		return true;
	} else if (primaryKeys->size() > primaryKeyList->size()) {
		return false;
	}

	KeyDataList::const_iterator it;
	
	for (it = primaryKeyList->begin() ; it != primaryKeyList->end() ; it++) {
		KeyDataList::const_iterator primaryKeyIterator = 
			primaryKeys->find(it->first);

		if (primaryKeyIterator != primaryKeys->end()) {

			if (*it->second < *primaryKeyIterator->second) {
				return true;
			} else if (*it->second > *primaryKeyIterator->second) {
				return false;
			}

		}

	}

	return false;

}

bool KeyDataCmp::operator() ( const KeyDataList* keyDataList1, const KeyDataList* keyDataList2 ) const {
	if (keyDataList1->size() < keyDataList2->size()) {
		return true;
	} else if (keyDataList1->size() > keyDataList2->size()) {
		return false;
	}

	KeyDataList::const_iterator it;
	
	for (it = keyDataList2->begin() ; it != keyDataList2->end() ; it++) {
		KeyDataList::const_iterator primaryKeyIterator = 
			keyDataList1->find(it->first);

		if (primaryKeyIterator != keyDataList1->end()) {

			if (it->second->getColumn().getSQLType() != primaryKeyIterator->second->getColumn().getSQLType()) {
				return false;
			}

			if (*it->second < *primaryKeyIterator->second) {
				return true;
			} else if (*it->second > *primaryKeyIterator->second) {
				return false;
			}

		}

	}

	return false;

}

		};
	};
};
