예제 #1
0
bool PgSQLType::canCastTo(PgSQLType type)
{
	// If the types are the same of belongs to the same category they naturally can be casted
	if(this->type_idx==type.type_idx ||
		(isCharacterType() && type.isCharacterType()) ||
		(isDateTimeType() && type.isDateTimeType()) ||
		(isNumericType() && type.isNumericType()) ||
		(isNetworkType() && type.isNetworkType()) ||

		//Polymorphics anyarray, anyrange, anynoarray, anyenum to anyelement
		((isPolymorphicType() && type==QString("anyelement")) ||
		 ((*this)==QString("anyelement") && type.isPolymorphicType())) ||

		//Character to network address
		((isCharacterType() || isNetworkType()) &&
		 (type.isCharacterType() || type.isNetworkType())) ||

		//Integer to OID
		((isIntegerType() || isOIDType()) &&
		 (type.isIntegerType() || type.isOIDType())) ||

		//abstime to integer
		((((*this)==QString("integer") || (*this)==QString("int4")) && type==QString("abstime")) ||
		 (((*this)==QString("abstime") && (type==QString("integer") || type==QString("int4"))))))

		return(true);

	return(false);
}
예제 #2
0
PgSQLType PgSQLType::parseString(const QString &str)
{
	QString type_str=str.toLower().simplified(), sptype, interv;
	bool with_tz=false;
	unsigned len=0, dim=0, srid=0;
	int prec=-1;
	int start=-1, end=-1;
	QStringList value, intervals;
	PgSQLType type;

	//Checking if the string contains one of interval types
	IntervalType::getTypes(intervals);
	while(!intervals.isEmpty())
	{
		interv=intervals.back();
		intervals.pop_back();

		start=type_str.indexOf(QRegExp(QString("( )") + interv.toLower()));
		if(start>=0)
		{
			type_str.remove(start, interv.size()+1);
			break;
		}
		else
			interv.clear();
	}

	//Check if the type contains "with time zone" descriptor
	with_tz=QRegExp(QString("(.)*(with time zone)(.)*")).exactMatch(type_str);

	//Removes the timezone descriptor
	type_str.remove(QRegExp(QString("(with)(out)*( time zone)")));

	//Count the dimension of the type and removes the array descriptor
	dim=type_str.count(QString("[]"));
	type_str.remove(QString("[]"));

	//Check if the type is a variable length type, e.g varchar(200)
	if(QRegExp(QString("(.)+\\(( )*[0-9]+( )*\\)")).indexIn(type_str) >=0)
	{
		start=type_str.indexOf('(');
		end=type_str.indexOf(')', start);
		len=type_str.mid(start+1, end-start-1).toUInt();
	}
	//Check if the type is a numeric type, e.g, numeric(10,2)
	else if(QRegExp(QString("(.)+\\(( )*[0-9]+( )*(,)( )*[0-9]+( )*\\)")).indexIn(type_str) >=0)
	{
		start=type_str.indexOf('(');
		end=type_str.indexOf(')', start);
		value=type_str.mid(start+1, end-start-1).split(',');
		len=value[0].toUInt();
		prec=value[1].toUInt();
	}
	//Check if the type is a spatial type (PostGiS), e.g, geography(POINTZ, 4296)
	else if(QRegExp(QString("(.)+\\(( )*[a-z]+(( )*(,)( )*[0-9]+( )*)?\\)"), Qt::CaseInsensitive).indexIn(type_str) >=0)
	{
		start=type_str.indexOf('(');
		end=type_str.indexOf(')', start);
		value=type_str.mid(start+1, end-start-1).split(',');
		sptype=value[0].toUpper();

		if(value.size() > 1)
			srid=value[1].toUInt();
	}

	//If the string matches one of the regexp above remove the analyzed parts
	if(start >=0 && end>=0)
		type_str.remove(start, end-start+1);

	/* The resultant string must be only the name of the type without [] and ().
	NOTE: Since the string was converted to lower case at start it's necessary to get
	it's original form from the input string in order to correctly create the type. */
	type_str=str.mid(str.indexOf(type_str, 0, Qt::CaseInsensitive),type_str.length()).trimmed();

	try
	{
		try
		{
			//Creates the type based on the extracted values
			type=PgSQLType(type_str);
		}
		catch(Exception &)
		{
			/* In case of error (specially with PostGiS types) split the string to remove
				the schema name and try to create the type once more */
			QStringList typname=type_str.split('.');

			if(typname.size()==2)
				type=PgSQLType(typname[1]);
			else
			{
				/* One last try it to check if the type has an entry on user defined types
		   as pg_catalog.[type name] */
				type=PgSQLType(QString("pg_catalog.") + type_str);
			}
		}

		type.setWithTimezone(with_tz);
		type.setDimension(dim);

		if(type.isNumericType() && len > 0 && prec >=0)
		{
			type.setLength(len);
			type.setPrecision(prec);
		}
		else if(type.isDateTimeType() && len > 0)
			type.setPrecision(len);
		else if(type.hasVariableLength() && len > 0)
			type.setLength(len);

		if(!interv.isEmpty())
			type.setIntervalType(IntervalType(interv));
		else if(!sptype.isEmpty())
			type.setSpatialType(SpatialType(sptype, srid));

		return(type);
	}
	catch(Exception &e)
	{
		throw Exception(e.getErrorMessage(), e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e, str);
	}
}