Announcement

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

    Width of integer types

    In working with various controls in both SmartGWT and SmartGWT.mobile, I've noticed that types that are declared as "INTEGER" in server-side DataSource definitions are mapped to java.lang.Integer values on the client side. Example:

    Code:
    [b]JSONUtils:141[/b] else if ("integer".equals(type)) value = getIntegerValue(jso, keyName);
    However, our record primary keys are all defined as Long (64-bit) values, and we expect that the 31-bit space of the Integer mapping will be fairly quickly exhausted by at least one table (line items for orders). I understand that the native JavaScript integer type is 53 bits wide; how do SmartClient and SmartGWT.mobile handle values that are greater than 2147483647? Will the runtimes perform some sort of autoexpansion, or is there going to be a train wreck when we pass the MAX_INT limit?

    #2
    Quick answer: this is not a problem for primaryKeys because they are parsed as JSON hence take on the full resolution of JavaScript's Number type. The conversion you're seeing would only happen in certain cases of accessing the PK value from Java code - to avoid it, ask for it as a String instead (since you presumably don't plan to do math on it). Or, specifically for PKs, just declare the type of the field as "text" on the server and it will be delivered as a String to the client.

    Longer answer: GWT supports the Long and BigDecimal data types via an opaque JavaScript data structure, but does not support automatic conversion to the JavaScript Number type (with possible precision loss) when passing values to/from JSNI. Currently the recommendation is that if you need to do *math operations* on such values inside the browser, they should be delivered as Strings and then parsed into BigDecimal / Long values in GWT Java code.

    Comment


      #3
      Originally posted by Isomorphic View Post
      Quick answer: this is not a problem for primaryKeys because they are parsed as JSON hence take on the full resolution of JavaScript's Number type. The conversion you're seeing would only happen in certain cases of accessing the PK value from Java code - to avoid it, ask for it as a String instead (since you presumably don't plan to do math on it). Or, specifically for PKs, just declare the type of the field as "text" on the server and it will be delivered as a String to the client.
      Declaring the PK as a text field is probably the best way to handle things generally, but the automatically-generated DataSources drop in this rather odd definition:
      Code:
      {
        hidden:true,
        name:"id",
        primaryKey:true,
        length:255,
        type:"sequence",
        required:false,
        canEdit:false
      }
      In SmartGWT.mobile, this hits an edge case that appears to work but makes me a bit twitchy (JSONUtils.java:172-176 in a few-day-old build):

      Code:
      // Sort of hacky, but it saves a lot of unnecessary casting on the Java side for the
      // most common case
      if (type == 'number' && value < 2147483648 && value > -2147483649 && value == Math.floor(value)) {
        type = 'integer';
      }
      Due to various inferences and type mappings, integer values greater than MAX_INT end up coming in on the mobile Record object as java.lang.Double values. This actually works, because of the ambiguity of how the JavaScript number type is being handled by the "GWT virtual machine", but the behavior is thoroughly unexpected and makes me paranoid. It's not causing problems that I notice right now, so it's clearly not a major priority for rework, but is there a chance that this mapping logic could be extended to map in large values as Long instead of Double?

      Longer answer: GWT supports the Long and BigDecimal data types via an opaque JavaScript data structure, but does not support automatic conversion to the JavaScript Number type (with possible precision loss) when passing values to/from JSNI. Currently the recommendation is that if you need to do *math operations* on such values inside the browser, they should be delivered as Strings and then parsed into BigDecimal / Long values in GWT Java code.
      This makes perfect sense, and obviously the client's not likely to be doing anything besides comparisons on PKs, since it's not safe to assign them client-side. This recommendation seems like something that ought to be explained in the main docs, and it also seems that the Right Thing would be for the server-side DataSource generator to turn PK fields into "text" fields instead of "sequence" fields, though I have no idea how much collateral damage this change would cause.

      Comment


        #4
        We've switched this around so that SmartGWT.mobile's internal storage for data coming from the server is Double objects, so this is roughly analogous to SmartClient/SmartGWT's internal storage as JavaScript Number values, hence there won't be a possibility of precision / range loss until you get into the territory of needing BigDecimal support.

        Longer term, we will probably have an option to explicitly tell the client-side engine what Java data type you want to use. But this value only in certain edge cases, since you typically use type-safe accessors like Record.getValueAsDouble() to access values.

        Comment


          #5
          I've migrated my DataSources to use string-based primary keys, and I've confirmed that the DataSourceLoader is labeling the fields as "text" (and SmartGWT appears to be consuming them properly). However, SmartGWT.mobile is still converting the primary-key IDs (which just happen to be strings that are correctly-formatted numbers) into java.lang.Doubles. Is there any update on getting the DataSource JSON parser to try to translate field values into the requested type?

          Comment

          Working...
          X