Project

General

Profile

marshal1.diff

Igor Skornyakov, 11/03/2022 10:24 AM

Download (37.3 KB)

View differences:

src/com/goldencode/p2j/persist/DynamicTablesHelper.java 2022-11-02 07:54:50 +0000
79 79
**     OM  20220914 Use MAX-WIDTH to generate custom sized varchar columns.
80 80
**     IAS 20221006 Added RAW type to the switch in the 'generateSchemaAst'.
81 81
**     IAS 20221013 Fixed setting of "serialize-name" and "serialize-hidden annotations".
82
**     IAS 20221014 Fixed 'column-codepage' support.
82 83
*/
83 84

  
84 85
/*
......
831 832
         {
832 833
            tableField.putAnnotation("col_lab", field.getColumnLabel());
833 834
         }
834
         
835
         if (field.getCodePage() != null)
835
         String cp = field.getCodePage();
836
         if (cp != null && !cp.trim().equals(""))
836 837
         {
837
            tableField.putAnnotation("codePage", field.getCodePage());
838
            tableField.putAnnotation("column-codepage", cp);
838 839
         }
839 840

  
840 841
         if (field.isSerializeHidden())
src/com/goldencode/p2j/persist/PropertyDefinition.java 2022-11-02 10:39:37 +0000
17 17
**     SVL 20201030 Added format, label and columnLabel fields.
18 18
**     OM  20201120 Added SCHEMA-MARSHAL implementation.
19 19
**     CA  20220909 Always marshal the schema, otherwise the remote side will not be able to rebuild the table.
20
**     IAS 20221029 Added support for missed properties.
21
**     IAS 20221102 Re-worked serialization for SCHEMA-MARSHAL == NONE.
20 22
*/
21 23

  
22 24
/*
......
76 78

  
77 79
import java.io.*;
78 80
import java.util.*;
81

  
82
import com.goldencode.p2j.persist.orm.*;
83
import com.goldencode.p2j.util.*;
84

  
79 85
import static com.goldencode.p2j.persist.AbstractTempTable.*;
80 86
import static com.goldencode.util.NativeTypeSerializer.*; 
81 87

  
......
117 123
   
118 124
   /** The column label of this property. */
119 125
   private String columnLabel;
120
   
126

  
127
   /** HELP attribute of this field. */
128
   private String help;
129
   
130
   /** INITIAL attribute of this field. */
131
   private String initial;
132

  
133
   /** Flag indicating the field should not be included in serialized output. */
134
   private boolean serializeHidden;
135
   
136
   /** Flag indicating the field is case-sensitive. */
137
   private boolean caseSensitive;
138

  
139
   /** Node type of field in XML output. */
140
   private String xmlNodeType;
141
   
142
   /** Code page of the CLOB field. */
143
   private String codePage;
144

  
121 145
   /**
122 146
    * The SCHEMA-MARSHAL level for the parent  temp-table. It is never {@code SM_DEFAULT} when object is to
123 147
    * be serialized. Always {@code SM_DEFAULT} for a read object.
......
303 327
      this.label = label;
304 328
      this.columnLabel = columnLabel;
305 329
   }
306
   
330

  
331
   /**
332
    * Create a new property definition.
333
    *
334
    * @param    prop
335
    *           The ORM field <code>Property</code>.
336
    */           
337
   public PropertyDefinition(Property prop)
338
   {
339
      this.name = prop.name;
340
      verifyType(prop._fwdType);
341
      this.type = prop._fwdType;
342
      int extent = prop.index > 0 ? 0 : prop.extent;
343
      this.extent = extent == 0 ? NO_EXTENT : extent;
344
      this.legacyName = prop.legacy;
345
      this.format = prop.format;
346
      this.label = prop.label;
347
      this.columnLabel = prop.columnLabel;
348
      this.help = prop.help;
349
      this.initial = prop.initial;
350
      this.serializeHidden = prop.serializeHidden;
351
      this.caseSensitive = prop.caseSensitive;
352
      this.xmlNodeType = prop.xmlNodeType;
353
      this.codePage = prop.codePage;
354
   }
307 355
   /**
308 356
    * Get the type of this property.
309 357
    * 
......
385 433
   }
386 434

  
387 435
   /**
436
    * Get help text of this property.
437
    *
438
    * @return help text of this property.
439
    */
440
   public String getHelp()
441
   {
442
      return help;
443
   }
444

  
445
   /**
446
    * Get initial value of this property.
447
    *
448
    * @return initial value of this property.
449
    */
450
   public String getInitial()
451
   {
452
      return initial;
453
   }
454

  
455
   /**
456
    * Get 'serialize hidden' flag of this property.
457
    *
458
    * @return 'serialize hidden' flag of this property.
459
    */
460
   public boolean isSerializeHidden()
461
   {
462
      return serializeHidden;
463
   }
464

  
465
   /**
466
    * Get 'case-sensitive' flag of this property.
467
    *
468
    * @return 'case-sensitive' flag of this property.
469
    */
470
   public boolean isCaseSensitive()
471
   {
472
      return caseSensitive;
473
   }
474

  
475
   
476
   /**
477
    * Get XML node type of this property.
478
    *
479
    * @return XML node type of this property.
480
    */
481
   public String getXmlNodeType()
482
   {
483
      return xmlNodeType;
484
   }
485

  
486
   /**
487
    * Get code page of this property.
488
    *
489
    * @return code page of this property.
490
    */
491
   public String getCodePage()
492
   {
493
      return codePage;
494
   }
495

  
496
   /**
388 497
    * Send the property definition to the specified output destination.
389 498
    * 
390 499
    * @param    out
......
396 505
   public final void writeExternal(ObjectOutput out)
397 506
   throws IOException
398 507
   {
508
      if (schemaMarshalLevel == SM_NONE)
509
      {
510
         throw new IllegalStateException("Should not be called if schemaMarshalLevel == SM_NONE");
511
      }
399 512
      boolean full = schemaMarshalLevel == SM_FULL || schemaMarshalLevel == SM_DEFAULT;
400
      // we can't omit the schema-related field information, as otherwise the remote side will not be able to
401
      // recreate the temp-table.
402
      boolean none = false; // schemaMarshalLevel == SM_NONE;
403 513
      
404
      writeString(out, none ? null : name);
405
      writeString(out, (type == null || none) ? null : type.getName());
406
      out.writeInt(none ? 0 : extent);
407
      writeString(out, none ? null : legacyName);
408
      writeString(out, full ? format : null);
409
      writeString(out, full ? label : null);
410
      writeString(out, full ? columnLabel : null);
514
      writeString(out, name);
515
      writeString(out, legacyName);
516
      writeString(out, type == null ? null : type.getName());
517
      out.writeInt(extent);
518
      writeString(out, initial);
519
      out.writeByte(serializeHidden ? 1 : 0);
520
      out.writeByte(caseSensitive ? 1 : 0);
521
      writeString(out, xmlNodeType);
522
      writeString(out, codePage);
523
      out.writeByte(full ? 1 : 0);
524
      if (!full )
525
      {
526
         return;
527
      }
528
      writeString(out, format);
529
      writeString(out, label);
530
      writeString(out, columnLabel);
531
      writeString(out, help);
411 532
   }
412 533
   
413 534
   /**
......
427 548
          ClassNotFoundException
428 549
   {
429 550
      name = readString(in);
551
      legacyName = readString(in);
430 552
      String tn = readString(in);
431 553
      type = (tn == null) ? null : Class.forName(tn);
432 554
      extent = in.readInt();
433
      legacyName = readString(in);
555
      initial = readString(in);
556
      serializeHidden = in.readByte() == 1;
557
      caseSensitive = in.readByte() == 1;
558
      xmlNodeType = readString(in);
559
      codePage = readString(in);
560
      boolean full = in.readByte() == 1;
561
      if (!full)
562
      {
563
         return;
564
      }
434 565
      format = readString(in);
435 566
      label = readString(in);
436 567
      columnLabel = readString(in);
568
      help = readString(in);
437 569
   }
438 570
   
439 571
   /**
src/com/goldencode/p2j/persist/TableMapper.java 2022-11-01 07:17:53 +0000
102 102
**     CA  20220601 getIndexFieldNames must return lowercased legacy names.
103 103
**     OM  20220914 Added MAX-WIDTH support for CHARACTER fields.
104 104
**     IAS 20221006 Added 'definedFormat' and 'definedLabel'.
105
**     IAS 20221018 Fixed processing of 'now' and 'today' INITIAL attribute value.
105 106
**     CA  20221031 Added JMX instrumentation for 'mapTemporaryTable'.
106 107
*/
107 108

  
......
2882 2883
                  {
2883 2884
                     if ("today".equalsIgnoreCase(text))
2884 2885
                     {
2885
                        initialValue = date.today();
2886
                        initialValue = new character(text);
2886 2887
                     }
2887 2888
                     else
2888 2889
                     {
......
2893 2894
                  {
2894 2895
                     if ("now".equalsIgnoreCase(text))
2895 2896
                     {
2896
                        initialValue = datetime.now();
2897
                        initialValue = new character(text);
2897 2898
                     }
2898 2899
                     else if (text.toUpperCase().indexOf('T') > 0)
2899 2900
                     {
......
2910 2911
                  {
2911 2912
                     if ("now".equalsIgnoreCase(text))
2912 2913
                     {
2913
                        initialValue = datetimetz.now();
2914
                        initialValue = new character(text);
2914 2915
                     }
2915 2916
                     else if (text.toUpperCase().indexOf('T') > 0)
2916 2917
                     {
src/com/goldencode/p2j/persist/TableWrapper.java 2022-11-03 14:24:10 +0000
28 28
**                  (so that relations, schema, etc is done on the server-side).
29 29
**     CA  20220428 Allow null peerDef at setPeerDef.
30 30
**     CA  20220602 Added basic support for transport of object instances over appserver call.
31
**     IAS 20221029 Added support for the SCHEMA-MARSHAL attribute.
32
**     IAS 20221102 Re-worked (de)serialization.
31 33
*/
32 34

  
33 35
/*
......
86 88
package com.goldencode.p2j.persist;
87 89

  
88 90
import static com.goldencode.util.NativeTypeSerializer.*; 
91
import static com.goldencode.p2j.persist.AbstractTempTable.*;
92

  
89 93
import java.io.*;
90 94
import java.lang.reflect.Array;
91 95
import java.util.*;
92 96

  
97
import com.goldencode.p2j.oo.lang.*;
93 98
import com.goldencode.p2j.util.*;
99
import com.goldencode.util.*;
94 100

  
95 101
/**
96 102
 * Any {@link TableResultSet} instance will be wrapped in a {@link TableWrapper} instance before
......
122 128

  
123 129
   /** Table name. */
124 130
   private String tableName;
131
   
132
   /** Flag indicating that table schema was received */  
133
   boolean receivedSchema = false;
134
   
135
   /** Table SCHEMA-MARSHAL attribute value encodes as int */ 
136
   private int schemaMarshalLevel;
125 137

  
126 138
   /**
127 139
    * Determines if this wrapper wraps data from a TABLE-HANDLE parameter. Necessary because of
......
682 694
         return;
683 695
      }
684 696

  
685
      writeString(out, tableName);
686
      out.writeByte(tableType);
687
      out.writeByte(numIndexes);
688
      writeString(out,indexes);
689
      writeString(out,xmlns);
690
      writeString(out,xmlPrefix);
697
      boolean writeSchema = schemaMarshalLevel != SM_NONE;
698
      out.writeByte(schemaMarshalLevel);
699
      if (writeSchema)
700
      {
701
         writeString(out, tableName);
702
         out.writeByte(tableType);
703
         out.writeByte(numIndexes);
704
         writeString(out,indexes);
705
         writeString(out,xmlns);
706
         writeString(out,xmlPrefix);
707
      }
691 708

  
692 709
      // write properties
693
      Set<Integer> blobProps = null;
694
      Set<Integer> objectProps = null;
710
      Set<Integer> blobProps = new HashSet<>();
711
      Set<Integer> objectProps = new HashSet<>();
695 712
      if (resultSet != null)
696 713
      {
697 714
         int idx = 0;
698 715
         while (resultSet.hasMoreProperties())
699 716
         {
700 717
            PropertyDefinition property = resultSet.nextProperty();
701
            out.writeByte(1);
702
            property.writeExternal(out);
718
            if (writeSchema)
719
            {
720
               property.setMarshalLevel(schemaMarshalLevel);
721
               out.writeByte(1);
722
               property.writeExternal(out);
723
            }
703 724

  
704 725
            if (property.getType() == blob.class)
705 726
            {
706
               if (blobProps == null)
707
               {
708
                  blobProps = new HashSet<>();
709
               }
710 727
               blobProps.add(idx);
711 728
            }
712 729
            else if (object.class.isAssignableFrom(property.getType()))
713 730
            {
714
               if (objectProps == null)
715
               {
716
                  objectProps = new HashSet<>();
717
               }
718 731
               objectProps.add(idx);
719 732
            }
720 733
            idx = idx + 1;
721 734
         }
722 735
      }
723
      out.writeByte(0);
724
   
736
      if (writeSchema)
737
      {
738
         out.writeByte(0);
739
      }
740
      writeIntSet(out, blobProps);
741
      writeIntSet(out, objectProps);
742

  
725 743
      // write data 
726 744
      if (resultSet != null)
727 745
      {
728 746
         while (resultSet.hasMoreRows())
729 747
         {
730 748
            Object[] row = resultSet.nextRow();
731
            if (blobProps != null)
749
            if (!blobProps.isEmpty())
732 750
            {
733 751
               Object[] row2 = new Object[row.length];
734 752
               System.arraycopy(row, 0, row2, 0, row2.length);
......
743 761
               row = row2;
744 762
            }
745 763
            
746
            if (objectProps != null)
764
            if (!objectProps.isEmpty())
747 765
            {
748 766
               Object[] row2 = new Object[row.length];
749 767
               System.arraycopy(row, 0, row2, 0, row2.length);
......
751 769
               {
752 770
                  if (row2[idx] instanceof object)
753 771
                  {
754
                     row2[idx] = new LegacyObject((object) row2[idx]);
772
                     row2[idx] = new LegacyObject((object<?>) row2[idx]);
755 773
                  }
756 774
               }
757 775
               
......
781 799
    * @throws   IOException
782 800
    *           In case of I/O errors.
783 801
    * @throws   ClassNotFoundException 
802
    *          If the class of property could not be found/loaded.
784 803
    */
804
   @Override
785 805
   public final void readExternal(ObjectInput in)
786 806
   throws IOException,
787 807
          ClassNotFoundException
......
802 822
         return;
803 823
      }
804 824
      
805
      tableName = readString(in);
806
      tableType = in.readByte();
807

  
808
      numIndexes = in.readByte();
809
      indexes = readString(in);
810
      xmlns = readString(in);
811
      xmlPrefix = readString(in);
812
      
813
      Set<Integer> blobProps = null;
814
      Set<Integer> objectProps = null;
815
      int idx = 0;
816
      properties = new ArrayList<>();
817
      do
825
      receivedSchema = in.readByte() != SM_NONE;
826
      if (receivedSchema)
818 827
      {
819
         if (in.readByte() == 0)
820
         {
821
            break;
822
         }
823
         PropertyDefinition pd = new PropertyDefinition();
824
         pd.readExternal(in);
825
         properties.add(pd);
826
         
827
         if (pd.getType() == blob.class)
828
         {
829
            if (blobProps == null)
830
            {
831
               blobProps = new HashSet<>();
832
            }
833
            blobProps.add(idx);
834
         }
835
         if (object.class.isAssignableFrom(pd.getType()))
836
         {
837
            if (objectProps == null)
838
            {
839
               objectProps = new HashSet<>();
840
            }
841
            objectProps.add(idx);
842
         }
843
         idx = idx + 1;
828
         tableName = readString(in);
829
         tableType = in.readByte();
830
         numIndexes = in.readByte();
831
         indexes = readString(in);
832
         xmlns = readString(in);
833
         xmlPrefix = readString(in);
834
         properties = new ArrayList<>();
835
         while (in.readByte() != 0)
836
         {
837
            PropertyDefinition pd = new PropertyDefinition();
838
            pd.readExternal(in);
839
            properties.add(pd);
840
            
841
         }
844 842
      }
845
      while (true);
843
      
844
      Set<Integer> blobProps = readIntSet(in);
845
      Set<Integer> objectProps = readIntSet(in);
846 846
      
847 847
      // read data
848 848
      rows = new ArrayList<>();
......
857 857
         
858 858
         Object[] row = (Object[]) next;
859 859
         rows.add(row);
860
         if (blobProps != null)
861
         {
862
            for (Integer i : blobProps)
863
            {
864
               row[i] = new blob(((MemoryBuffer) row[i]).getValue());
865
            }
866
         }
867
         if (objectProps != null)
868
         {
869
            for (Integer i : objectProps)
870
            {
871
               LegacyObject ref = (LegacyObject) row[i];
872
               ObjectVar v = new ObjectVar(ref.getType());
873
               v.assign(ref.restore());
874
               row[i] = v;
875
            }
876
         }
860
         blobProps.stream().forEach(i -> row[i] = new blob(((MemoryBuffer) row[i]).getValue()));
861
         objectProps.stream().forEach(i -> {
862
            LegacyObject ref = (LegacyObject) row[i];
863
            ObjectVar<? extends _BaseObject_> v = new ObjectVar<>(ref.getType());
864
            v.assign(ref.restore());
865
            row[i] = v;
866
         });
877 867

  
878 868
         next = in.readObject();
879 869
         rowsMeta.add((Object[]) next);
......
890 880
      }
891 881
   }
892 882

  
883
   /** 
884
    * Check that table schema was received.
885
    * 
886
    * @return <code>true</code> if table schema was received.
887
    */
888
   public boolean isReceivedSchema() 
889
   {
890
      return receivedSchema;
891
   }
892

  
893 893
   /**
894 894
    * Determines if this wrapper wraps data from a TABLE-HANDLE parameter.
895 895
    *
......
921 921
      this.tableHandle = tableHandle;
922 922
   }
923 923

  
924
   /** Get encoded table SCHEMA-MARSHAL attribute value.
925
    * 
926
    * @return encoded table SCHEMA-MARSHAL attribute value.
927
    */
928
   public int getSchemaMarshalLevel()
929
   {
930
      return schemaMarshalLevel;
931
   }
932

  
933
   /** Set encoded table SCHEMA-MARSHAL attribute value.
934
    * 
935
    * @param schemaMarshalLevel 
936
    *        encoded table SCHEMA-MARSHAL attribute value.
937
    */
938
   public void setSchemaMarshalLevel(int schemaMarshalLevel)
939
   {
940
      this.schemaMarshalLevel = schemaMarshalLevel;
941
   }
942

  
924 943
   /**
925 944
    * Initialize this wrapper with the info from the given temp-table.
926 945
    * 
src/com/goldencode/p2j/persist/TempTableBuilder.java 2022-10-29 16:22:57 +0000
122 122
**     OM  20220914 Added MAX-WIDTH support for CHARACTER fields.
123 123
**     IAS 20221003 Fixed default value of the PRIMARY attribute
124 124
**     IAS 20221014 Added COMHANDLE to the 'datatypesMatchLen' map
125
**     IAS 20221029 Added support for missed properties.
125 126
*/
126 127

  
127 128
/*
......
1340 1341
                              character    label,
1341 1342
                              character    columnLabel)
1342 1343
   {
1344
      return addNewField(name, type, extent, format, initial, label, columnLabel,
1345
               null, null, null, false, false);
1346
   }
1347
   /**
1348
    * Adds a field with the specified properties to the temp-table.
1349
    * This method is the P2J equivalent of <code>ADD-NEW-FIELD</code> method
1350
    * of Progress 4GL.
1351
    * <p>
1352
    * When a parameter is set to null, it means it was not specified by the business logic.
1353
    *
1354
    * @param   name
1355
    *          The name of the field to be created in the temp-table.
1356
    * @param   type
1357
    *          The data type of the specified field.
1358
    * @param   extent
1359
    *          An integer expression specifying the extent of an array.
1360
    * @param   format
1361
    *          The data format for the defined data type. If empty or unknown, format is
1362
    *          replaced with default format. Null value means that format is not used in
1363
    *          ADD-NEW-FIELD.
1364
    * @param   initial
1365
    *          An expression that evaluates to the initial value of the defined field.
1366
    *          TODO: this method will probably be overloaded because of this.
1367
    * @param   label
1368
    *          The label of the defined field. If <code>null</code> or unknown the name
1369
    *          parameter will be used.
1370
    * @param   columnLabel
1371
    *          The label of the column associated with the defined field
1372
    * @param   help 
1373
    * @param   xmlNodeType 
1374
    * @param   codePage 
1375
    * @param   serializeHidden 
1376
    * @param   caseSensitive 
1377
    *
1378
    * @return  <code>true</code> on success.
1379
    */
1380
   public logical addNewField(character    name,
1381
                              character    type,
1382
                              integer      extent,
1383
                              character    format,
1384
                              BaseDataType initial,
1385
                              character    label,
1386
                              character    columnLabel,
1387
                              character    help,
1388
                              character    xmlNodeType,
1389
                              character    codePage,
1390
                              boolean      serializeHidden,
1391
                              boolean      caseSensitive)
1392
   {
1343 1393
      addFunctionCalled = true;
1344 1394
      
1345 1395
      if (_prepared())
......
1397 1447
      
1398 1448
      String labelStr = label != null ? label.getValue() : null;
1399 1449
      String columnLabelStr = columnLabel != null ? columnLabel.getValue() : null;
1450
      String helpStr = help != null ? help.getValue() : null;
1451
      String codePageStr = codePage != null ? codePage.getValue() : null;
1452
      String xmlNodeTypeStr = xmlNodeType != null ? xmlNodeType.getValue() : null;
1400 1453
      
1401 1454
      // Note: case-sensitivity and CLOB code page cannot be specified using P4GL ADD-NEW-FIELD method
1402 1455
      long ext = extent == null || extent.getValue() == 1 ? 0 : extent.getValue();
1403 1456
      P2JField field = new P2JField(fieldName, parmType, ext, formatStr,
1404
                                    initial, labelStr, columnLabelStr, false, null, null, false, null, null,
1405
                                    null, null, false, 0, 0);
1457
                                    initial, labelStr, columnLabelStr, caseSensitive, 
1458
                                    codePageStr, helpStr, serializeHidden, null, null,
1459
                                    null, xmlNodeTypeStr, false, 0, 0);
1406 1460
      addField(field);
1407 1461
      return new logical(true);
1408 1462
   }
......
2749 2803
         PropertyDefinition propertyDefinition = iter.next();
2750 2804
         addNewField(propertyDefinition);
2751 2805
      }
2806
      this.namespaceURI(tableWrapper.getXmlns());
2807
      this.namespacePrefix(tableWrapper.getXmlPrefix());
2752 2808
      tempTablePrepare(tableWrapper.getTableName());
2753 2809
      TemporaryBuffer.insertAllRows(tableWrapper,
2754 2810
                                    (Temporary) defaultBufferHandle().getResource(),
......
3114 3170
                  new character(dataType),
3115 3171
                  extent,
3116 3172
                  new character(propertyDefinition.getFormat()),
3117
                  null,
3173
                  new character(propertyDefinition.getInitial()),
3118 3174
                  new character(propertyDefinition.getLabel()),
3119
                  new character(propertyDefinition.getColumnLabel()));
3175
                  new character(propertyDefinition.getColumnLabel()),
3176
                  new character(propertyDefinition.getHelp()),
3177
                  new character(propertyDefinition.getXmlNodeType()),
3178
                  new character(propertyDefinition.getCodePage()),
3179
                  propertyDefinition.isSerializeHidden(),
3180
                  propertyDefinition.isCaseSensitive());
3120 3181
   }
3121 3182
   
3122 3183
   /**
src/com/goldencode/p2j/persist/TempTableResultSet.java 2022-10-29 16:24:55 +0000
31 31
**     SVL 20210701 Added clearRows.
32 32
**     CA  20221006 Do not access tableHandle() in the FWD runtime, get the TempTable instance directly.  
33 33
**                  Refs #6826
34
**     IAS 20221029 Re-worked 'init' method.
34 35
*/
35 36

  
36 37
/*
......
189 190
    * @param    append
190 191
    *           Flag indicating this table is sent in APPEND mode.
191 192
    *           
192
    * @throws   ClassNotFoundException
193
    *           If the type of a property can not be resolved to a class.
194 193
    */
195 194
   public TempTableResultSet(Temporary dmo, boolean input, boolean output, boolean append)
196
//   throws ClassNotFoundException
197 195
   {
198 196
      this(dmo, input, output, append, true);
199 197
   }
......
358 356
    * TODO: improve this (i.e. use an open cursor or some other alternative to not read the data
359 357
    *       in memory)
360 358
    * 
361
    * @throws   ClassNotFoundException
362
    *           If the type of a property can not be resolved to a class.
363 359
    */
364 360
   private void init(boolean copyRows)
365
//   throws ClassNotFoundException
366 361
   {
367 362
      TemporaryBuffer buffer = (TemporaryBuffer) ((BufferReference) dmo).buffer();
368 363
      
......
387 382
      {
388 383
         dmoPropIndex.put(dmoProps[i], i);
389 384
      }
390
      PropertyDefinition[] props = new PropertyDefinition[dmoProps.length];
391
      
392
      Iterator<Property> iter = dmoInfo.getFields(false); // skip properties that are not accessible via the DMO's API.
393
      while (iter.hasNext())
394
      {
395
         Property prop = iter.next();
396
         // the Properties whose extent fields were denormalized are treated as simple ones 
397
         int extent = prop.index > 0 ? 0 : prop.extent;
398
         if (extent == 0)
399
         {
400
            props[dmoPropIndex.get(prop.name)] = 
401
               new PropertyDefinition(prop.name,
402
                                      prop._fwdType,
403
                                      prop.legacy,
404
                                      prop.format,
405
                                      prop.label,
406
                                      prop.columnLabel);
407
         }
408
         else
409
         {
410
            props[dmoPropIndex.get(prop.name)] = 
411
               new PropertyDefinition(prop.name,
412
                                      prop._fwdType,
413
                                      extent,
414
                                      prop.legacy,
415
                                      prop.format,
416
                                      prop.label,
417
                                      prop.columnLabel);
418
         }
419
      }
420
      
421
      java.util.List<PropertyDefinition> lprops = new ArrayList<>();
422
      for (int i = 0; i < props.length; i++)
423
      {
424
         if (props[i] != null)
425
         {
426
            lprops.add(props[i]);
427
         }
428
      }
385
      
386
      Iterable<Property> iter = () -> dmoInfo.getFields(false); // skip properties that are not accessible via the DMO's API.
387
      Map<Integer, PropertyDefinition> mprops = new TreeMap<>();
388
      for (Property prop: iter)
389
      {
390
         mprops.put(dmoPropIndex.get(prop.name), new PropertyDefinition(prop));
391
      }
392
      List<PropertyDefinition> lprops = new ArrayList<>(mprops.values());
429 393

  
430 394
      if (copyRows)
431 395
      {
src/com/goldencode/p2j/persist/TemporaryBuffer.java 2022-11-03 14:21:59 +0000
623 623
**                           they are not.
624 624
**     OM  20221027          Use Dialect API to create and drop sequences.
625 625
**     CA  20221031          Added JMX instrumentation for TABLE[-HANDLE] parameter processing.
626
**     IAS 20221102          Added error reporting for SCHEMA-MARSHAL == NONE.
626 627
**     OM  20221103          New class names for FQLPreprocessor, FQLExpression, FQLBundle, and FQLCache.
628
**     IAS 20221103          Fixed support for a binded table parameter.
627 629
*/
628 630

  
629 631
/*
......
2230 2232
                  src.setTable(dstDMO);
2231 2233
               }
2232 2234
            }
2235
            else if (bind)
2236
            {
2237
               RecordBuffer rb = ((BufferReference) dstDMO).buffer();
2238
               DmoMeta meta = rb.getDmoInfo();
2239
               Iterable<Property> props = () -> meta.getFields(false);
2240
               List<PropertyDefinition> pdl = new ArrayList<>();
2241
               for ( Property p: props)
2242
               {
2243
                  pdl.add(new PropertyDefinition(p));
2244
               }
2245
               src.getResultSet().setProperties(pdl);
2246
            }
2233 2247
            else
2234 2248
            {
2235 2249
               // TODO: remote table-handle param ??
......
2600 2614
         else
2601 2615
         {
2602 2616
            TableWrapper resultSet = src.getResultSet();
2617
            if (!resultSet.isReceivedSchema())
2618
            {
2619
               ErrorManager.recordOrThrowError(12323);
2620
            }
2603 2621
            if (resultSet != null && resultSet.isValid() && resultSet.getTableName() != null)
2604 2622
            {
2605 2623
               TempTableBuilder builder = new TempTableBuilder();
src/com/goldencode/p2j/persist/orm/DmoMeta.java 2022-10-18 08:44:59 +0000
39 39
**                  to a better suited name.
40 40
**     OM  20220706 The objects returned by getDatabaseIndexes() carry the legacy names, too.
41 41
**     OM  20220914 Use MAX-WIDTH to generate custom sized varchar columns.
42
**     IAS 20221018 Fixed processing of 'now' and 'today' INITIAL attribute value.
42 43
*/
43 44

  
44 45
/*
......
1591 1592
                     {
1592 1593
                        if (bdtType == date.class)
1593 1594
                        {
1594
                           init = "today".equalsIgnoreCase(p.initial) ? date.today() : new date(p.initial);
1595
                           init = "today".equalsIgnoreCase(p.initial) ? new character(p.initial) : new date(p.initial);
1595 1596
                        }
1596 1597
                        else if (bdtType == datetime.class)
1597 1598
                        {
1598 1599
                           if ("now".equalsIgnoreCase(p.initial))
1599 1600
                           {
1600
                              init = datetime.now();
1601
                              init =  new character(p.initial);
1601 1602
                           }
1602 1603
                           else if (p.initial.toUpperCase().indexOf('T') > 0)
1603 1604
                           {
......
1614 1615
                        {
1615 1616
                           if ("now".equalsIgnoreCase(p.initial))
1616 1617
                           {
1617
                              init = datetimetz.now();
1618
                              init = new character(p.initial);
1618 1619
                           }
1619 1620
                           else if (p.initial.toUpperCase().indexOf('T') > 0)
1620 1621
                           {
src/com/goldencode/p2j/persist/serial/XmlImport.java 2022-10-18 08:45:19 +0000
42 42
**     OM  20220914 Use MAX-WIDTH to generate custom sized varchar columns.
43 43
**     IAS 20220926 Fixed READ-XMLSCHEMA support.
44 44
**     IAS 20221014 More fixes to READ-XMLSCHEMA support.
45
**     IAS 20221018 Fixed processing of 'now' and 'today' INITIAL attribute value.
45 46
*/
46 47

  
47 48
/*
......
1866 1867
                              // Unable to set initial value '<value>' from XML Schema for field '<field>'.
1867 1868
                              return false;
1868 1869
                           }
1869
                           
1870
                           try
1871
                           {
1872
                              Constructor<? extends BaseDataType> ctor = 
1873
                                 (Constructor<? extends BaseDataType>) fwdType.getConstructor(String.class);
1874
                              defVal = ctor.newInstance(defaultStrVal);
1875
                           }
1876
                           catch (NoSuchMethodException | IllegalAccessException | 
1877
                                  InstantiationException | InvocationTargetException e)
1878
                           {
1879
                              ErrorManager.recordOrShowError(13143, defaultStrVal, fieldName);
1880
                              // Unable to set initial value '<value>' from XML Schema for field '<field>'.
1881
                              return false;
1870
                           if (fwdType == date.class && "today".equalsIgnoreCase(defaultStrVal))
1871
                           {
1872
                                defVal = new character("today"); 
1873
                           }
1874
                           else if ((fwdType == datetime.class || fwdType == datetimetz.class) &&
1875
                                     "now".equalsIgnoreCase(defaultStrVal))
1876
                           {
1877
                              defVal = new character("now"); 
1878
                           }
1879
                           else
1880
                           {
1881
                              try
1882
                              {
1883
                                 Constructor<? extends BaseDataType> ctor = 
1884
                                    (Constructor<? extends BaseDataType>) fwdType.getConstructor(String.class);
1885
                                 defVal = ctor.newInstance(defaultStrVal);
1886
                              }
1887
                              catch (NoSuchMethodException | IllegalAccessException | 
1888
                                     InstantiationException | InvocationTargetException e)
1889
                              {
1890
                                 ErrorManager.recordOrShowError(13143, defaultStrVal, fieldName);
1891
                                 // Unable to set initial value '<value>' from XML Schema for field '<field>'.
1892
                                 return false;
1893
                              }
1882 1894
                           }
1883 1895
                        }
1884 1896
                        
src/com/goldencode/p2j/util/AppServerHelper.java 2022-11-02 07:58:35 +0000
77 77
**     CA  20220428 Fixed memptr, extent, table arguments when the request is remote.
78 78
**     CA  20220602 Added basic support for transport of object instances over appserver call.
79 79
**     CA  20220912 If a dataset from the call has no buffers added to it, set it to unknown.
80
**     IAS 20221029 Fixed TableParameter processing.
80 81
*/
81 82

  
82 83
/*
......
2660 2661

  
2661 2662
                  boolean input = (mode == 'I' || mode == 'U');
2662 2663
                  boolean output = (mode == 'O' || mode == 'U');
2664
                  
2665
                  int schemaMarshalLevel = tableParam.getSchemaMarshalLevel();
2663 2666

  
2664
//               try
2665
//               {
2666 2667
                  arg = new TableWrapper(new TempTableResultSet(tempDMO, input, output, append, input));
2667 2668
                  String tableName = ((BufferImpl) tempDMO).buffer().getDmoInfo().legacyTable;
2668 2669
                  ((TableWrapper) arg).setTableName(tableName);
2669
//               }
2670
//               catch (ClassNotFoundException e)
2671
//               {
2672
//                  String err = String.format("Could not process temp DMO %s as a parameter!", 
2673
//                                              tempDMO.getClass().getName());
2674
//                  
2675
//                  throw new IllegalArgumentException(err, e);
2676
//               }
2670
                  ((TableWrapper) arg).setSchemaMarshalLevel(schemaMarshalLevel);
2671
                  handle tableHandle = ((Buffer) tempDMO).tableHandle();
2672
                  if (tableHandle._isValid())
2673
                  {
2674
                     ((TableWrapper) arg).init((TempTable) tableHandle.getResource());
2675
                  }
2677 2676

  
2678 2677
                  try
2679 2678
                  {
src/com/goldencode/p2j/util/ErrorManager.java 2022-11-02 11:52:19 +0000
247 247
**                           with namesakes in DMO. See #6694.
248 248
**     IAS 20221003          Fixed error message for error 3131
249 249
**     IAS 20221006          Reverted error message for error 3131 change.
250
**     IAS 20221102          Added error 12323 support.
250 251
*/
251 252

  
252 253
/*
......
3083 3084
         case 12301: msg = "Source and target are the same table in temp-table copy operation for %1"; break;     // dataset-copy (itself)
3084 3085
         case 12303: msg = "COPY-TEMP-TABLE requires %1 and %2 columns to match exactly unless the fourth loose-mode parameter is passed as TRUE"; break; // dataset-copy (table structure not matching)
3085 3086
         case 12310: msg = "Caller and called dataset parameters have different number of members"; break;
3086
         
3087
         case 12323: msg = "A NO-SCHEMA-MARSHAL table cannot be used as a parameter where the receiving side does not have a pre-prepared schema"; break;
3087 3088
         case 12344: msg = "Cannot turn on TRACKING-CHANGES for a static temp-table unless DEFINED with a BEFORE-TABLE phrase"; break;
3088 3089
         case 12352: msg = "Argument %1 to query callback method must be a valid query event name such as OFF-END"; break;
3089 3090
         case 12355: msg = "TRACKING-CHANGES may not be turned on for a non-dataset temp-table"; break;
src/com/goldencode/p2j/util/TableParameter.java 2022-10-29 16:28:13 +0000
38 38
**                  INPUT-OUTPUT mode, and the DATASET-HANDLE, DATASET, TABLE-HANDLE or TABLE versions.
39 39
**     CA  20220727 Fixed OO dataset/table parameters (at the method definition and method call) when there is
40 40
**                  an APPEND option.
41
**     IAS 20221029 Added SCHEMA-MARSHAL attribute support.
41 42
*/
42 43

  
43 44
/*
......
134 135
   /** {@code true} if the parameter mode is OUTPUT or INPUT-OUTPUT. */
135 136
   private boolean output = false;
136 137
   
138
   /** Table SCHEMA-MARSHAL attribute value encodes as int */ 
139
   private int schemaMarshalLevel;
140
   
137 141
   /** Flag indicating this is a TABLE-HANDLE argument. */
138 142
   private boolean isTableHandle = false;
139 143
   
......
218 222
      this.options     = options;
219 223
      this.input       = input;
220 224
      this.output      = output;
225
      this.schemaMarshalLevel = ((AbstractTempTable)this.tableHandle.unwrapTempTable()).
226
                                       getSchemaMarshalLevel();
221 227
   }
222 228
   
223 229
   /**
......
596 602
      return parameterIndex;
597 603
   }
598 604
   
605
   /** Get encoded table SCHEMA-MARSHAL attribute value.
606
    * 
607
    * @return encoded table SCHEMA-MARSHAL attribute value.
608
    */
609
   public int getSchemaMarshalLevel()
610
   {
611
      return schemaMarshalLevel;
612
   }
613

  
599 614
   /**
600 615
    * Set 1-based index of the table parameter (in declaration of the function).
601 616
    *