void PgSQLTypeWidget::setAttributes(PgSQLType type, DatabaseModel *model, unsigned usr_type_conf, bool oid_types, bool pseudo_types) { try { int idx; type_cmb->blockSignals(true); listPgSQLTypes(type_cmb, model, usr_type_conf, oid_types, pseudo_types); type_cmb->blockSignals(false); //Get the passed type index idx=type_cmb->findText(~type); //Select the type on the combo type_cmb->setCurrentIndex(idx); length_sb->setValue(type.getLength()); precision_sb->setValue(type.getPrecision()); dimension_sb->setValue(type.getDimension()); idx=interval_cmb->findText(~(type.getIntervalType())); interval_cmb->setCurrentIndex(idx); timezone_chk->setChecked(type.isWithTimezone()); this->type=type; updateTypeFormat(); } catch(Exception &e) { throw Exception(e.getErrorMessage(),e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); } }
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); }
void Type::setElement(PgSQLType elem) { if(PgSQLType::getUserTypeIndex(this->getName(true), this) == !elem) throw Exception(Exception::getErrorMessage(ERR_USER_TYPE_SELF_REFERENCE).arg(this->getName(true)), ERR_USER_TYPE_SELF_REFERENCE,__PRETTY_FUNCTION__,__FILE__,__LINE__); else if(elem!=QString("\"any\"") && (elem.isOIDType() || elem.isPseudoType() || elem.isUserType() || elem.isArrayType())) throw Exception(Exception::getErrorMessage(ERR_ASG_INV_ELEMENT_TYPE).arg(this->getName(true)), ERR_ASG_INV_ELEMENT_TYPE,__PRETTY_FUNCTION__,__FILE__,__LINE__); setCodeInvalidated(element != elem); this->element=elem; }
bool PgSQLType::isEquivalentTo(PgSQLType type) { unsigned this_idx=0, type_idx=0; static vector<QStringList> types={ {QString("int2"),QString("smallint")}, {QString("int4"),QString("integer")}, {QString("int8"),QString("bigint")}, {QString("decimal"),QString("numeric")}, {QString("character varying"),QString("varchar")}, {QString("character"), QString("char")}, {QString("bit varying"),QString("varbit")} }; //If the types are equal there is no need to perform further operations if(*this==type) return(true); //Getting the index which the this type is in for(QStringList list : types) { if(list.contains(~(*this))) break; this_idx++; } //Getting the index which 'type' is in for(QStringList list : types) { if(list.contains(~type)) break; type_idx++; } return(this_idx < types.size() && type_idx < types.size() && this_idx==type_idx && this->isArrayType()==type.isArrayType()); }
void Parameter::setType(PgSQLType type) { if(!type.isArrayType() && is_variadic) throw Exception(ERR_INV_USE_VARIADIC_PARAM_MODE ,__PRETTY_FUNCTION__,__FILE__,__LINE__); this->type=type; }
void Column::setType(PgSQLType type) { //An error is raised if the column receive a pseudo-type as data type. if(type.isPseudoType()) throw Exception(ERR_ASG_PSDTYPE_COLUMN,__PRETTY_FUNCTION__,__FILE__,__LINE__); else this->type=type; }
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); } }