void PgSQLTypeWidget::updateTypeFormat(void) { try { QVariant data; //Gets the data related to the current selected data type data=type_cmb->itemData(type_cmb->currentIndex()); //If the data value (index) is 0 indicates that the type is a built-in one if(data.toUInt()==0) type=type_cmb->currentText(); else //Case the index is greated than zero indicates that the type is a user-defined one type=data.toUInt(); length_sb->setEnabled(type.hasVariableLength()); timezone_chk->setVisible(type==QString("timestamp") || type==QString("time")); timezone_lbl->setVisible(timezone_chk->isVisible()); precision_sb->setEnabled(type.acceptsPrecision()); dimension_sb->setEnabled(type!=QString("void")); interval_cmb->setVisible(type==QString("interval")); interval_lbl->setVisible(interval_cmb->isVisible()); spatial_cmb->setVisible(type.isGiSType()); spatial_lbl->setVisible(type.isGiSType()); variation_lbl->setVisible(type.isGiSType()); srid_lbl->setVisible(type.isGiSType()); srid_spb->setVisible(type.isGiSType()); var_m_chk->setVisible(type.isGiSType()); var_z_chk->setVisible(type.isGiSType()); if(spatial_cmb->isVisible()) { SpatialType spatial_tp; spatial_tp=SpatialType(spatial_cmb->currentText(), srid_spb->value()); if(var_z_chk->isChecked() && var_m_chk->isChecked()) spatial_tp.setVariation(SpatialType::var_zm); else if(var_m_chk->isChecked()) spatial_tp.setVariation(SpatialType::var_m); else if(var_z_chk->isChecked()) spatial_tp.setVariation(SpatialType::var_z); type.setSpatialType(spatial_tp); } type.setLength(length_sb->value()); type.setPrecision(precision_sb->value()); type.setDimension(dimension_sb->value()); type.setIntervalType(interval_cmb->currentText()); type.setWithTimezone(timezone_chk->isChecked()); format_txt->setPlainText(*type); } catch(Exception &e) { throw Exception(e.getErrorMessage(),e.getErrorType(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); } }
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); } }