Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    DataSource.getPrimaryKeyFieldNames issue

    I'm using smartgwt-power-3.1-p20130728.

    I used the following code that resulted into an exception:
    Code:
    final String[] primaryKeyFieldNames = getDataSource().getPrimaryKeyFieldNames();
    
    java.lang.ClassCastException: com.google.gwt.core.client.JavaScriptObject$ cannot be cast to [Ljava.lang.String;
        at com.smartgwt.client.data.DataSource.getPrimaryKeyFieldNames(DataSource.java)

    #2
    A second question. I actually need such a function for a ResultSet that has to observer changes only of some record(s):
    Code:
        protected AdvancedCriteria createCriteriaToMatchAnyRecordByPk(Record... records) {
            //final String[] primaryKeyFieldNames = getDataSource().getPrimaryKeyFieldNames();//throws cast exception
            final String[] primaryKeyFieldNames = getDataSource().getPrimaryKeyFields().getAttributes();
            List<AdvancedCriteria> criteriaList = Lists.newArrayList();
            for (Record record : records) {
                List<AdvancedCriteria> recordCriteriaList = Lists.newArrayList();
                for (String pkFieldName : primaryKeyFieldNames) {
                    recordCriteriaList.add(new AdvancedCriteria(pkFieldName, OperatorId.EQUALS, record.getAttribute(pkFieldName)));//TODO: check whether the value conversion to string creates a wrong criteria
                }
                criteriaList.add(new AdvancedCriteria(OperatorId.AND, recordCriteriaList.toArray(new AdvancedCriteria[0])));
            }
            return new AdvancedCriteria(OperatorId.OR,criteriaList.toArray(new AdvancedCriteria[0]));
        }
    The function should work with any datasource with defined PK.

    1) Exists already such a function in the framework? I didn't find it.

    2) See my TODO. Can be implemented in a way to work for PKs with different types (String, Number), without checking the type of PK field and calling the related record.getAttributeXXX method? I found record.getAttributeAsObject but I didn't find AdvancedCriteria(String fieldName, OperatorId operator, Object value). I don't need to convert from JS to Java the values, I only need to create a good criteria.

    Comment


      #3
      We'll check on your report on a JSNI / typecast crash. On your other questions:

      1. No, there's no framework method like this

      2. There isn't a constructor or addCriterion() method taking Object because the criteria system doesn't understand arbitrary Objects. This means you'll have to detect the type of the PK value and cast to that type.

      Comment


        #4
        The ClassCastException when calling getPrimaryKeyFieldNames will be resolved in tonight's nightly build.

        Comment


          #5
          I've build a new version of the function I've mentioned previously, but is very likely to not be correct once the framework supports other types, like BigDecimal or BigInteger:
          Code:
              public static AdvancedCriteria createCriteriaToMatchAnyRecordByPk(DataSource datasource, Record... records) {
                  if(records == null || records.length == 0){
                      return new AdvancedCriteria();
                  }
                  //final String[] primaryKeyFieldNames = getDataSource().getPrimaryKeyFieldNames();//throws cast exception
                  final Record primaryKeyFields = datasource.getPrimaryKeyFields();
                  final String[] primaryKeyFieldNames = primaryKeyFields.getAttributes();
                  List<Criterion> criteriaList = Lists.newArrayList();
                  for (Record record : records) {
                      List<Criterion> recordCriteriaList = Lists.newArrayList();
                      for (String pkFieldName : primaryKeyFieldNames) {
                          final Object value = record.getAttributeAsObject(pkFieldName);
                          if(value instanceof String){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (String)value));
                          } else if(value instanceof Boolean){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (Boolean)value));
                          } else if(value instanceof Date){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (Date)value));
                          } else if(value instanceof Float){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (Float)value));
                          } else if(value instanceof Integer){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (Integer)value));
                          } else if(value instanceof Long){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (Long)value));
                          } else if(value instanceof String[]){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (String[])value));
                          } else if(value instanceof Boolean[]){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (Boolean[])value));
                          } else if(value instanceof Date[]){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (Date[])value));
                          } else if(value instanceof Float[]){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (Float[])value));
                          } else if(value instanceof Integer[]){
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, (Integer[])value));
                          } else {
                              SmartGwtLog.logWarn("createCriteriaToMatchAnyRecordByPk() - Not supported type of object: " + value.getClass() + ". Will be converted to String.", "CriteriaFactory");
                              recordCriteriaList.add(new Criterion(pkFieldName, OperatorId.EQUALS, record.getAttribute(pkFieldName)));//TODO: check whether the value conversion to string creates a wrong criteria
                          }
                      }
                      criteriaList.add(new Criterion(OperatorId.AND, recordCriteriaList.toArray(new Criterion[0])));
                  }
                  return new AdvancedCriteria(OperatorId.OR,criteriaList.toArray(new Criterion[0]));
              }
          It seems to me that the inner part of the function (all instanceof checks) should be part of the framework, maybe as a new Criterion/AdvancedCriteria constructor with Object as input value parameter.

          Btw, AdvancedCriteria misses some constructors from Criterion class, like Criterion(String, OperatorId, Long), Criterion(String, OperatorId, Long[]).
          Regarding the support for BigDecimal/BigInteger, the SDLDataSource creates such objects, so would be good to have them supported also in the Criterion class.

          Regards,
          Mihnea

          Comment

          Working...
          X