Project

General

Profile

marshal4.diff

Igor Skornyakov, 11/09/2022 12:48 AM

Download (71.5 KB)

View differences:

src/com/goldencode/p2j/persist/DataSet.java 2022-11-08 09:46:52 +0000
92 92
**                  an APPEND option.
93 93
**     CA  20220918 Automatically delete top-nav queries created dynamically by the DATASET.
94 94
**     CA  20221031 Added JMX instrumentation for DATASET[-HANDLE] parameter processing.
95
**     IAS 20221108 Fixed support for SCHEMA-MARSHAL == NONE.
95 96
*/
96 97

  
97 98
/*
......
151 152

  
152 153
import com.goldencode.p2j.jmx.*;
153 154
import com.goldencode.p2j.persist.TemporaryBuffer.CopyTableMode;
155
import com.goldencode.p2j.persist.orm.*;
154 156
import com.goldencode.p2j.persist.serial.*;
155 157
import com.goldencode.p2j.security.*;
156 158
import com.goldencode.p2j.util.*;
......
673 675
                  wrapper = dsSrc.getDatasetWrapper().getTableWrapper(k - 1);
674 676
               }
675 677
               
678
               if (dsSrc.isRemoteParameter()  && !wrapper.isReceivedSchema())
679
               {
680
                  RecordBuffer rb = ((BufferReference) targetDmo).buffer();
681
                  DmoMeta meta = rb.getDmoInfo();
682
                  Iterator<Property> props = meta.getFields(false);
683
                  List<PropertyDefinition> pdl = new ArrayList<>();
684
                  props.forEachRemaining(p -> pdl.add(new PropertyDefinition(p)));
685
                  wrapper.setProperties(pdl);
686
               }
676 687
               TemporaryBuffer.insertAllRows(
677 688
                     wrapper,
678 689
                     (Temporary) targetDmo,
......
851 862
         {
852 863
            if (dsParam.isByReference() || dsParam.isRemoteParameter())
853 864
            {
865
               // check if all tables contain schema.
866
               if (!dsParam.getDatasetWrapper().getTableDefs().stream().
867
                        allMatch(DsTableDefinition::isReceivedSchema))
868
               {
869
                  ErrorManager.recordOrThrowError(12323);
870
               }
854 871
               // if [dsParam] is remote, the dataset was rehydrated when [dsParam] was created
855 872
               // do not copy now for 2nd time. Since it is an [input] param we can use the 
856 873
               // dataset handle directly.
......
3899 3916
      List<BufferImpl> localBuffers = new ArrayList<>(bufs.length);
3900 3917
      for (Buffer buf : bufs)
3901 3918
      {
3919
         if (buf == null)
3920
         {
3921
            continue;
3922
         }
3902 3923
         BufferImpl bufRef = ((BufferImpl) buf).ref();
3903 3924
         if (initClass == null)
3904 3925
         {
src/com/goldencode/p2j/persist/DataSetParameter.java 2022-11-08 09:48:28 +0000
39 39
**                  INPUT-OUTPUT mode, and the DATASET-HANDLE, DATASET, TABLE-HANDLE or TABLE versions.
40 40
**     CA  20220727 Fixed OO dataset/table parameters (at the method definition and method call) when there is
41 41
**                  an APPEND option.
42
**     IAS 20221108 Fixed support for SCHEMA-MARSHAL == NONE. Re-worked indexes (de)serialization.
42 43
*/
43 44

  
44 45
/*
......
542 543
         {
543 544
            DsTableDefinition tableDef = tableDefs.get(k);
544 545
            
546
            if (!tableDef.isReceivedSchema())
547
            {
548
               continue;
549
            }
545 550
            if (!tableDef.isBeforeTable())
546 551
            {
547 552
               Iterator<PropertyDefinition> props = tableDef.propertyIterator();
548 553
               String idx = tableDef.getIndexes();
549 554
               String xmlns = tableDef.getXmlns();
550 555
               String prefix = tableDef.getXmlPrefix();
551
               buffs[k] = TempTableBuilder.createRemoteTable(tableDef.getName(), props, idx, xmlns, prefix);
556
               List<IndexDefinition> indexDefs = tableDef.getIndexDefs();
557
               TempTableBuilder ttb = new TempTableBuilder(); 
558
               if (indexDefs != null)
559
               {
560
                  buffs[k] = ttb.createRemoteTable(tableDef.getName(), 
561
                           props, () -> indexDefs.stream().forEach(ix -> ix.addTo(ttb)), 
562
                           xmlns, prefix);
563
               }
564
               else
565
               {
566
                  buffs[k] = ttb.createRemoteTable(tableDef.getName(), 
567
                           props, idx, xmlns, prefix);
568
               }
552 569
               
553 570
               if (tableDef.isAfterTable() && tableDef.getPeerDef() != null)
554 571
               {
src/com/goldencode/p2j/persist/DatasetWrapper.java 2022-11-08 09:49:11 +0000
17 17
**                  (so that relations, schema, etc is done on the server-side).
18 18
**     CA  20221102 Added a static serialization ID - required when enabling AOP method tracing (see 
19 19
**                  p2j.aspects.ltw.MethodTraceAspect).
20
**     IAS 20221108 Fixed support for SCHEMA-MARSHAL == NONE.
20 21
*/
21 22

  
22 23
/*
......
573 574
         tw = new TableWrapper();
574 575
         tw.readExternal(new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray())));
575 576
         
577
         tw.receivedSchema = tdef.receivedSchema;
576 578
         if (bres != null)
577 579
         {
578 580
            TableWrapper btw = new TableWrapper(bres);
src/com/goldencode/p2j/persist/DsTableDefinition.java 2022-11-08 09:51:57 +0000
2 2
** Module   : DsTableDefinition.java
3 3
** Abstract : A container for a DataSet Table metadata.
4 4
**
5
** Copyright (c) 2019-2021, Golden Code Development Corporation.
5
** Copyright (c) 2019-2022, Golden Code Development Corporation.
6 6
**
7 7
** -#- -I- --Date-- ---------------------------------------Description---------------------------------------
8 8
** 001 OM  20130708 Created initial version.
......
20 20
**     OM  20210309 Do not use DmoMeta as key in TableMapper because temp-tables share the same DmoMeta.
21 21
**     SVL 20210614 Added copyRows parameter.
22 22
**     SVL 20210701 Added clearRows.
23
**     IAS 20221108 Fixed support for SCHEMA-MARSHAL == NONE. Re-worked (de)serialization.
23 24
*/
24 25

  
25 26
/*
......
79 80

  
80 81
import java.io.*;
81 82
import java.util.*;
83
import java.util.stream.*;
82 84
import com.goldencode.p2j.util.*;
83 85
import static com.goldencode.p2j.persist.AbstractTempTable.*;
84 86
import static com.goldencode.util.NativeTypeSerializer.*;
......
90 92
public class DsTableDefinition
91 93
implements Externalizable
92 94
{
95
   /** Flag indicating that table schema was received */  
96
   boolean receivedSchema = false;
93 97
   /** The name of this table. */
94 98
   private String name;
95 99
   
......
125 129
   
126 130
   /** The ERROR-STRING attribute for this table definition. */
127 131
   private String errorString = null;
132
   /** List of indexes' descriptors */
133
   private List<IndexDefinition> indexDefs = null;
128 134
   
129 135
   /**
130 136
    * A string with all indexes of this table definition encoded as a {@code String}.
......
188 194
         case SM_FULL:
189 195
         case SM_DEFAULT:
190 196
            // full table schema is serialized with table parameter
191
            this.indexes = TableMapper.getLegacyIndexInfo(parentTable);
192
            this.numIndexes = this.indexes.split("\\.").length;
193 197
            this.xmlns = parentTable.namespaceURI().toStringMessage();
194 198
            this.xmlPrefix = parentTable.namespacePrefix().toStringMessage();
195 199
            this.xmlNodeName = parentTable.getXmlNodeName().toStringMessage();
196 200
            // no break, fall through
197 201
            
198 202
         case SM_MIN:
199
            // marshals:
200
            //    field names, data types, and extents;
201
            //    temp-table ERROR-STRING
202
            // does NOT marshal:
203
            //    index descriptions
204
            //    field information (label, help, field validation expression, and so on (?))
203
            this.indexes = TableMapper.getLegacyIndexInfo(parentTable);
204
            this.numIndexes = this.indexes.split("\\.").length;
205
            this.indexDefs = TableMapper.getLegacyIndexes(parentTable).map(lif -> new IndexDefinition(lif)).
206
                     collect(Collectors.toList());
205 207
            this.errorString = defBuff.errorString().toStringMessage();
206 208
            // no break, fall through
207 209
         
......
277 279
      this.name = name;
278 280
   }
279 281
   
282
   /** 
283
    * Check that table schema was received.
284
    * 
285
    * @return <code>true</code> if table schema was received.
286
    */
287
   public boolean isReceivedSchema() 
288
   {
289
      return receivedSchema;
290
   }
291
   
280 292
   /**
281 293
    * Check whether this is a definition of an AFTER-TABLE.
282 294
    * 
......
386 398
   }
387 399
   
388 400
   /**
401
    * Get List of indexes' descriptors.
402
    * @return the List of indexes' descriptors.
403
    */
404
   public List<IndexDefinition> getIndexDefs()
405
   {
406
      return indexDefs;
407
   }
408

  
409
   /**
389 410
    * Sets the XML namespace for this table definition.
390 411
    * 
391 412
    * @param   xmlns
......
502 523
               "A custom result set must not be specified when calling this method!");
503 524
      }
504 525
      
505
      return new ArrayList<>(properties);
526
      return new ArrayList<>(properties != null ? properties : Collections.emptyList());
506 527
   }
507 528
   
508 529
   /**
......
562 583
   public final void writeExternal(ObjectOutput out)
563 584
   throws IOException
564 585
   {
586
      boolean writeSchema = schemaMarshalLevel != SM_NONE;
587
      out.writeByte(schemaMarshalLevel);
565 588
      writeString(out, name);
566 589
      out.writeByte(tableType);
590
      if (writeSchema)
591
      {
567 592
      out.writeByte(numIndexes);
568 593
      writeString(out, indexes);
594
         writeList(out, indexDefs);
569 595
      writeString(out, xmlns);
570 596
      writeString(out, xmlPrefix);
571
      writeString(out, xmlNodeName);
572
      writeString(out, errorString);
597
      }
573 598
      
574
      // write properties as a byte(1) separated list, ended with a byte(0)
575
      Set<Integer> blobProps = null;
599
      // write properties
600
      Set<Integer> blobProps = new HashSet<>();
601
      Set<Integer> objectProps = new HashSet<>();
576 602
      if (resultSet != null)
577 603
      {
578 604
         int idx = 0;
579 605
         while (resultSet.hasMoreProperties())
580 606
         {
581 607
            PropertyDefinition property = resultSet.nextProperty();
608
            if (writeSchema)
609
            {
582 610
            property.setMarshalLevel(schemaMarshalLevel);
583 611
            out.writeByte(1);
584 612
            property.writeExternal(out);
613
            }
585 614
            
586 615
            if (property.getType() == blob.class)
587 616
            {
588
               if (blobProps == null)
589
               {
590
                  blobProps = new HashSet<>();
591
               }
592 617
               blobProps.add(idx);
593 618
            }
619
            else if (object.class.isAssignableFrom(property.getType()))
620
               {
621
               objectProps.add(idx);
622
            }
594 623
            idx = idx + 1;
595 624
         }
596 625
      }
626
      if (writeSchema)
627
      {
597 628
      out.writeByte(0);
629
      }
630
      writeIntSet(out, blobProps);
631
      writeIntSet(out, objectProps);
598 632
      
599 633
      // write data 
600 634
      if (resultSet != null)
......
647 681
   throws IOException,
648 682
          ClassNotFoundException
649 683
   {
684
      receivedSchema = in.readByte() != SM_NONE;
650 685
      name = readString(in);
651 686
      tableType = in.readByte();
687
      if (receivedSchema)
688
      {
652 689
      numIndexes = in.readByte();
653 690
      indexes = readString(in);
691
         indexDefs = readList(in, () -> new IndexDefinition());
654 692
      xmlns = readString(in);
655 693
      xmlPrefix = readString(in);
656
      xmlNodeName = readString(in);
657
      errorString = readString(in);
658
      
659
      // read meta info separated by byte(1). The list ends with a byte(0).
660 694
      properties = new ArrayList<>();
661
      Set<Integer> blobProps = null;
662
      int idx = 0;
663
      boolean moreProperties = (in.readByte() == 1); 
664
      while (moreProperties) 
695
         while (in.readByte() != 0)
665 696
      {
666 697
         PropertyDefinition pd = new PropertyDefinition();
667 698
         pd.readExternal(in);
668 699
         properties.add(pd);
669 700
         
670
         // check if there are more to read:
671
         moreProperties = (in.readByte() == 1);
672

  
673
         if (pd.getType() == blob.class)
674
         {
675
            if (blobProps == null)
676
            {
677
               blobProps = new HashSet<>();
678 701
            }
679
            blobProps.add(idx);
680 702
         }
681
         idx = idx + 1;
682
      }
703
      Set<Integer> blobProps = readIntSet(in);
704
      Set<Integer> objectProps = readIntSet(in);
683 705
      
684 706
      // read data
685 707
      rows = new ArrayList<>();
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/IndexDefinition.java 2022-11-04 14:40:16 +0000
1
/*
2
** Module   : IndexDefinition.java
3
** Abstract : A container for a table index metadata.
4
**
5
** Copyright (c) 2022, Golden Code Development Corporation.
6
**
7
** -#- -I- --Date-- ---------------------------------------Description---------------------------------------
8
** 001 IAS 20221104 Created initial version.
9
*/
10

  
11
/*
12
** This program is free software: you can redistribute it and/or modify
13
** it under the terms of the GNU Affero General Public License as
14
** published by the Free Software Foundation, either version 3 of the
15
** License, or (at your option) any later version.
16
**
17
** This program is distributed in the hope that it will be useful,
18
** but WITHOUT ANY WARRANTY; without even the implied warranty of
19
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
** GNU Affero General Public License for more details.
21
**
22
** You may find a copy of the GNU Affero GPL version 3 at the following
23
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
24
** 
25
** Additional terms under GNU Affero GPL version 3 section 7:
26
** 
27
**   Under Section 7 of the GNU Affero GPL version 3, the following additional
28
**   terms apply to the works covered under the License.  These additional terms
29
**   are non-permissive additional terms allowed under Section 7 of the GNU
30
**   Affero GPL version 3 and may not be removed by you.
31
** 
32
**   0. Attribution Requirement.
33
** 
34
**     You must preserve all legal notices or author attributions in the covered
35
**     work or Appropriate Legal Notices displayed by works containing the covered
36
**     work.  You may not remove from the covered work any author or developer
37
**     credit already included within the covered work.
38
** 
39
**   1. No License To Use Trademarks.
40
** 
41
**     This license does not grant any license or rights to use the trademarks
42
**     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
43
**     of Golden Code Development Corporation. You are not authorized to use the
44
**     name Golden Code, FWD, or the names of any author or contributor, for
45
**     publicity purposes without written authorization.
46
** 
47
**   2. No Misrepresentation of Affiliation.
48
** 
49
**     You may not represent yourself as Golden Code Development Corporation or FWD.
50
** 
51
**     You may not represent yourself for publicity purposes as associated with
52
**     Golden Code Development Corporation, FWD, or any author or contributor to
53
**     the covered work, without written authorization.
54
** 
55
**   3. No Misrepresentation of Source or Origin.
56
** 
57
**     You may not represent the covered work as solely your work.  All modified
58
**     versions of the covered work must be marked in a reasonable way to make it
59
**     clear that the modified work is not originating from Golden Code Development
60
**     Corporation or FWD.  All modified versions must contain the notices of
61
**     attribution required in this license.
62
*/
63

  
64

  
65
package com.goldencode.p2j.persist;
66

  
67
import static com.goldencode.util.NativeTypeSerializer.*; 
68
import java.io.*;
69
import java.util.*;
70
import java.util.stream.*;
71

  
72
import com.goldencode.p2j.persist.TableMapper.*;
73
import com.goldencode.p2j.util.*;
74

  
75
/**
76
 * Container for a table index metadata. Used to send the metadata of a
77
 * DMO to a remote side, when remote appserver calls are involved.
78
 */
79
public class IndexDefinition
80
implements Externalizable
81
{
82
   /** The legacy name of this index. */
83
   private String legacyName;
84
   
85
   /**
86
    * Determine if the index is a primary index: the one with the "primary" annotation or, if
87
    * there is no such one, the first in the definition order.
88
    */
89
   private boolean effectivePrimary;
90
   
91
   /** Determine if the index is an unique index. */
92
   private boolean unique;
93
   
94
   /** Determine if the index is a word-index index. */
95
   private boolean word;
96
   
97
   /** Index components (fields with sorting directions). */
98
   private List<IndexComponentDefinition> components;
99

  
100
   /**
101
    * Default c'tor
102
    */
103
   public IndexDefinition()
104
   {
105
      
106
   }
107

  
108
   /**
109
    * Constructor 
110
    * @param lii
111
    *        ORM index info
112
    *        
113
    */
114
   public IndexDefinition(LegacyIndexInfo lii)
115
   {
116
      this.legacyName = lii.getLegacyName();
117
      this.effectivePrimary = lii.isEffectivePrimary();
118
      this.unique = lii.isUnique();
119
      this.word = lii.isWord();
120
      this.components = lii.indexComponents().map(lici -> new IndexComponentDefinition(lici)).
121
                                              collect(Collectors.toList());
122
   }
123
   
124
   /**
125
    * Add index to the <code>TableBuilder</code>
126
    * @param tb
127
    *        <code>TableBuilder</code> instance.
128
    */
129
   public void addTo(TempTableBuilder tb)
130
   {
131
      
132
      tb.addNewIndex(new character(legacyName),
133
                     new logical(unique),
134
                     new logical(effectivePrimary),
135
                     new logical(word));
136
      components.stream().forEach(
137
               c -> tb.addFieldToIndex(legacyName, 
138
                                       c.fieldLegacyName, 
139
                                       c.effectiveDescending ? "desc" : "asc"));
140
   }
141
   
142
   /**
143
    * Read the index definition from the specified input source.
144
    * 
145
    * @param    in
146
    *           The input source from which the index definition will be read.
147
    *
148
    * @throws   IOException
149
    *           In case of I/O errors.
150
    *
151
    * @throws  ClassNotFoundException
152
    *          If the class of property could not be found/loaded.
153
    */
154
   @Override
155
   public void readExternal(ObjectInput in) 
156
   throws IOException, 
157
          ClassNotFoundException
158
   {
159
      legacyName = readString(in);
160
      byte flags = in.readByte();
161
      effectivePrimary = (flags & 1) != 0;
162
      unique = (flags & 2) != 0;
163
      word = (flags & 4) != 0;
164
      components = readList(in, () -> new IndexComponentDefinition());
165
   }
166

  
167
   /**
168
    * Send the index definition to the specified output destination.
169
    * 
170
    * @param    out
171
    *           The output destination to which the index definition will be sent.
172
    *
173
    * @throws   IOException
174
    *           In case of I/O errors.
175
    */
176
   @Override
177
   public void writeExternal(ObjectOutput out) 
178
   throws IOException
179
   {
180
      writeString(out, legacyName);
181
      out.writeByte((effectivePrimary ? 1 : 0) | (unique ? 2 : 0) | (word ? 1 : 0));
182
      writeList(out, components);
183
   }
184

  
185
   /** A container with an index component information. */
186
   public static class IndexComponentDefinition
187
   implements Externalizable
188
   {
189
      /** The legacy name of the field participating in the index. */
190
      private String fieldLegacyName;
191
      
192
      /** Determines if this component has descending sorting. */
193
      private boolean effectiveDescending;
194
      
195
      /**
196
       * Default c'tor
197
       */
198
      public IndexComponentDefinition()
199
      {
200
         
201
      }
202
      /**
203
       * Constructor
204
       * @param lici
205
       *        DMO ORM index component info.
206
       */
207
      public IndexComponentDefinition(LegacyIndexComponentInfo lici)
208
      {
209
         this.fieldLegacyName = lici.fieldLegacyName;
210
         this.effectiveDescending = lici.effectiveDescending;
211
      }
212
      
213

  
214
      
215
      /**
216
       * Read the index definition from the specified input source.
217
       * 
218
       * @param    in
219
       *           The input source from which the index component definition will be read.
220
       *
221
       * @throws   IOException
222
       *           In case of I/O errors.
223
       *
224
       * @throws  ClassNotFoundException
225
       *          If the class of property could not be found/loaded.
226
       */
227
      @Override
228
      public void readExternal(ObjectInput in) 
229
      throws IOException, 
230
             ClassNotFoundException
231
      {
232
         fieldLegacyName = readString(in);
233
         effectiveDescending = in.readByte() != 0;
234
      }
235

  
236
      /**
237
       * Send the index definition to the specified output destination.
238
       * 
239
       * @param    out
240
       *           The output destination to which the index component definition will be sent.
241
       *
242
       * @throws   IOException
243
       *           In case of I/O errors.
244
       */
245
      @Override
246
      public void writeExternal(ObjectOutput out) 
247
               throws IOException
248
      {
249
         writeString(out, fieldLegacyName);
250
         out.writeByte(effectiveDescending ? 1 : 0);
251
      }
252
   }
253
}
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-04 14:15:48 +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'.
107
*      IAS 20222204 Added 'indexComponents()' and 'getLegacyIndexes' methods.
106 108
*/
107 109

  
108 110
/*
......
163 165
import java.lang.reflect.*;
164 166
import java.util.*;
165 167
import java.util.concurrent.*;
168
import java.util.stream.Stream;
166 169

  
167 170
import com.goldencode.p2j.persist.annotation.*;
168 171
import com.goldencode.p2j.persist.annotation.Trigger;
......
788 791
   }
789 792
   
790 793
   /**
794
    * Get stream for the indexes associated with the given temporary table.
795
    *
796
    * @param    tt
797
    *           Temp table object.
798
    * @return   stream for the indexes associated with the given temporary table.
799
    */
800
   public static Stream<TableMapper.LegacyIndexInfo> getLegacyIndexes(TempTable tt)
801
   {
802
      TempTableMapper mapper = locateTemp(tt);
803
      
804
      synchronized (mapper)
805
      {
806
         return mapper.legacyIndexInfo(tt);
807
      }
808
   }
809
   /**
791 810
    * Get information about the index associated with the DMO referenced by the given buffer,
792 811
    * as a string.
793 812
    *
......
2663 2682
      }
2664 2683
      
2665 2684
      /**
2685
       * Get stream for the indexes associated with the given temporary table.
2686
       *
2687
       * @param    tt
2688
       *           Temp table object.
2689
       * @return   stream for the indexes associated with the given temporary table.
2690
       */
2691
      private Stream<LegacyIndexInfo> legacyIndexInfo(TempTable tt)
2692
      {
2693
         LegacyTableInfo tableInfo = p2j.get(tt);
2694
         return new ArrayList<>(tableInfo.idx).stream();
2695
      }
2696

  
2697
      /**
2666 2698
       * Get the legacy index name of converted index, which is defined by the specified backing
2667 2699
       * temp table.
2668 2700
       *
......
2882 2914
                  {
2883 2915
                     if ("today".equalsIgnoreCase(text))
2884 2916
                     {
2885
                        initialValue = date.today();
2917
                        initialValue = new character(text);
2886 2918
                     }
2887 2919
                     else
2888 2920
                     {
......
2893 2925
                  {
2894 2926
                     if ("now".equalsIgnoreCase(text))
2895 2927
                     {
2896
                        initialValue = datetime.now();
2928
                        initialValue = new character(text);
2897 2929
                     }
2898 2930
                     else if (text.toUpperCase().indexOf('T') > 0)
2899 2931
                     {
......
2910 2942
                  {
2911 2943
                     if ("now".equalsIgnoreCase(text))
2912 2944
                     {
2913
                        initialValue = datetimetz.now();
2945
                        initialValue = new character(text);
2914 2946
                     }
2915 2947
                     else if (text.toUpperCase().indexOf('T') > 0)
2916 2948
                     {
......
3118 3150
      }
3119 3151
      
3120 3152
      /**
3153
       * Get a stream for the index components.
3154
       * 
3155
       * @return iterator for the index components.
3156
       */
3157
      public Stream<LegacyIndexComponentInfo> indexComponents()
3158
      {
3159
         return Arrays.stream(components);
3160
      }
3161
      /**
3121 3162
       * Returns index information as a string. Format of this string is described in
3122 3163
       * {@link Buffer#indexInformation(int)}
3123 3164
       *
......
3216 3257
   static class LegacyIndexComponentInfo
3217 3258
   {
3218 3259
      /** The legacy name of the field participating in the index. */
3219
      private final String fieldLegacyName;
3260
      public final String fieldLegacyName;
3220 3261
      
3221 3262
      /** Determines if this component has descending sorting. */
3222
      private final boolean effectiveDescending;
3263
      public final boolean effectiveDescending;
3223 3264
      
3224 3265
      /**
3225 3266
       * Create a new index component information container, holding field name and sorting
src/com/goldencode/p2j/persist/TableWrapper.java 2022-11-07 18:05:19 +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.
33
**     IAS 20221104 Added structured indexes data.
31 34
*/
32 35

  
33 36
/*
......
86 89
package com.goldencode.p2j.persist;
87 90

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

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

  
99
import com.goldencode.p2j.oo.lang.*;
93 100
import com.goldencode.p2j.util.*;
101
import com.goldencode.util.*;
94 102

  
95 103
/**
96 104
 * Any {@link TableResultSet} instance will be wrapped in a {@link TableWrapper} instance before
......
122 130

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

  
126 140
   /**
127 141
    * Determines if this wrapper wraps data from a TABLE-HANDLE parameter. Necessary because of
......
159 173
    */
160 174
   private String indexes = null;
161 175

  
176
   /** List of indexes' descriptors */
177
   private List<IndexDefinition> indexDefs = null;
178
   
162 179
   /** Flag indicating if the source is a JSON table. */
163 180
   private boolean fromJson = false;
164 181
   
......
423 440
   }
424 441
   
425 442
   /**
443
    * Get List of indexes' descriptors.
444
    * @return the List of indexes' descriptors.
445
    */
446
   public List<IndexDefinition> getIndexDefs()
447
   {
448
      return indexDefs;
449
   }
450
   /**
426 451
    * Get the {@link #xmlns XML namespace}.
427 452
    * 
428 453
    * @return   See above.
......
573 598
           "A custom result set must not be specified when calling this method!");
574 599
      }
575 600

  
576
      return new ArrayList<PropertyDefinition>(properties);
601
      return new ArrayList<PropertyDefinition>(
602
               properties != null ? properties : Collections.emptyList());
577 603
   }
578 604

  
579 605
   /**
......
682 708
         return;
683 709
      }
684 710

  
685
      writeString(out, tableName);
686
      out.writeByte(tableType);
687
      out.writeByte(numIndexes);
688
      writeString(out,indexes);
689
      writeString(out,xmlns);
690
      writeString(out,xmlPrefix);
711
      boolean writeSchema = schemaMarshalLevel != SM_NONE;
712
      out.writeByte(schemaMarshalLevel);
713
      if (writeSchema)
714
      {
715
         writeString(out, tableName);
716
         out.writeByte(tableType);
717
         out.writeByte(numIndexes);
718
         writeString(out,indexes);
719
         writeList(out, indexDefs);
720
         writeString(out,xmlns);
721
         writeString(out,xmlPrefix);
722
      }
691 723

  
692 724
      // write properties
693
      Set<Integer> blobProps = null;
694
      Set<Integer> objectProps = null;
725
      Set<Integer> blobProps = new HashSet<>();
726
      Set<Integer> objectProps = new HashSet<>();
695 727
      if (resultSet != null)
696 728
      {
697 729
         int idx = 0;
698 730
         while (resultSet.hasMoreProperties())
699 731
         {
700 732
            PropertyDefinition property = resultSet.nextProperty();
701
            out.writeByte(1);
702
            property.writeExternal(out);
733
            if (writeSchema)
734
            {
735
               property.setMarshalLevel(schemaMarshalLevel);
736
               out.writeByte(1);
737
               property.writeExternal(out);
738
            }
703 739

  
704 740
            if (property.getType() == blob.class)
705 741
            {
706
               if (blobProps == null)
707
               {
708
                  blobProps = new HashSet<>();
709
               }
710 742
               blobProps.add(idx);
711 743
            }
712 744
            else if (object.class.isAssignableFrom(property.getType()))
713 745
            {
714
               if (objectProps == null)
715
               {
716
                  objectProps = new HashSet<>();
717
               }
718 746
               objectProps.add(idx);
719 747
            }
720 748
            idx = idx + 1;
721 749
         }
722 750
      }
723
      out.writeByte(0);
724
   
751
      if (writeSchema)
752
      {
753
         out.writeByte(0);
754
      }
755
      writeIntSet(out, blobProps);
756
      writeIntSet(out, objectProps);
757

  
725 758
      // write data 
726 759
      if (resultSet != null)
727 760
      {
728 761
         while (resultSet.hasMoreRows())
729 762
         {
730 763
            Object[] row = resultSet.nextRow();
731
            if (blobProps != null)
764
            if (!blobProps.isEmpty())
732 765
            {
733 766
               Object[] row2 = new Object[row.length];
734 767
               System.arraycopy(row, 0, row2, 0, row2.length);
......
743 776
               row = row2;
744 777
            }
745 778
            
746
            if (objectProps != null)
779
            if (!objectProps.isEmpty())
747 780
            {
748 781
               Object[] row2 = new Object[row.length];
749 782
               System.arraycopy(row, 0, row2, 0, row2.length);
......
751 784
               {
752 785
                  if (row2[idx] instanceof object)
753 786
                  {
754
                     row2[idx] = new LegacyObject((object) row2[idx]);
787
                     row2[idx] = new LegacyObject((object<?>) row2[idx]);
755 788
                  }
756 789
               }
757 790
               
......
781 814
    * @throws   IOException
782 815
    *           In case of I/O errors.
783 816
    * @throws   ClassNotFoundException 
817
    *          If the class of property could not be found/loaded.
784 818
    */
819
   @Override
785 820
   public final void readExternal(ObjectInput in)
786 821
   throws IOException,
787 822
          ClassNotFoundException
......
802 837
         return;
803 838
      }
804 839
      
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
840
      receivedSchema = in.readByte() != SM_NONE;
841
      if (receivedSchema)
818 842
      {
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;
843
         tableName = readString(in);
844
         tableType = in.readByte();
845
         numIndexes = in.readByte();
846
         indexes = readString(in);
847
         indexDefs = readList(in, () -> new IndexDefinition());
848
         xmlns = readString(in);
849
         xmlPrefix = readString(in);
850
         properties = new ArrayList<>();
851
         while (in.readByte() != 0)
852
         {
853
            PropertyDefinition pd = new PropertyDefinition();
854
            pd.readExternal(in);
855
            properties.add(pd);
856
            
857
         }
844 858
      }
845
      while (true);
859
      
860
      Set<Integer> blobProps = readIntSet(in);
861
      Set<Integer> objectProps = readIntSet(in);
846 862
      
847 863
      // read data
848 864
      rows = new ArrayList<>();
......
857 873
         
858 874
         Object[] row = (Object[]) next;
859 875
         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
         }
876
         blobProps.stream().forEach(i -> row[i] = new blob(((MemoryBuffer) row[i]).getValue()));
877
         objectProps.stream().forEach(i -> {
878
            LegacyObject ref = (LegacyObject) row[i];
879
            ObjectVar<? extends _BaseObject_> v = new ObjectVar<>(ref.getType());
880
            v.assign(ref.restore());
881
            row[i] = v;
882
         });
877 883

  
878 884
         next = in.readObject();
879 885
         rowsMeta.add((Object[]) next);
......
890 896
      }
891 897
   }
892 898

  
899
   /** 
900
    * Check that table schema was received.
901
    * 
902
    * @return <code>true</code> if table schema was received.
903
    */
904
   public boolean isReceivedSchema() 
905
   {
906
      return receivedSchema;
907
   }
908

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

  
940
   /** Get encoded table SCHEMA-MARSHAL attribute value.
941
    * 
942
    * @return encoded table SCHEMA-MARSHAL attribute value.
943
    */
944
   public int getSchemaMarshalLevel()
945
   {
946
      return schemaMarshalLevel;
947
   }
948

  
949
   /** Set encoded table SCHEMA-MARSHAL attribute value.
950
    * 
951
    * @param schemaMarshalLevel 
952
    *        encoded table SCHEMA-MARSHAL attribute value.
953
    */
954
   public void setSchemaMarshalLevel(int schemaMarshalLevel)
955
   {
956
      this.schemaMarshalLevel = schemaMarshalLevel;
957
   }
958

  
924 959
   /**
925 960
    * Initialize this wrapper with the info from the given temp-table.
926 961
    * 
......
933 968
      Buffer defBuff = (Buffer) table.defaultBufferHandle().getResource();
934 969
      this.indexes = TableMapper.getLegacyIndexInfo(table);
935 970
      this.numIndexes = indexes.split("\\.").length; // TODO: "." or "\\." ?
971
      this.indexDefs = TableMapper.getLegacyIndexes(table).map(lif -> new IndexDefinition(lif)).
972
                                                           collect(Collectors.toList());
936 973
      this.xmlns = defBuff.namespaceURI().toStringMessage();
937 974
      this.xmlPrefix = defBuff.namespacePrefix().toStringMessage();
938 975
   }
src/com/goldencode/p2j/persist/TempTableBuilder.java 2022-11-09 05:45:24 +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.
126
**     IAS 20221104 Added indexes parsing for input remote table.
127
**     IAS 20221108 Replaced static 'createRemoteTable' with a regular one.
125 128
**     CA  20221108 BEFORE-TABLE's name is always trimmed to max 32 chars length.
126 129
*/
127 130

  
......
314 317
    *           The XML namespace.
315 318
    * @param    xmlPrefix
316 319
    *           The XML prefix.
320
    * @return   default buffer for the table
317 321
    */
318
   public static BufferImpl createRemoteTable(String tableName,
322
   public BufferImpl createRemoteTable(String tableName,
319 323
                                              Iterator<PropertyDefinition> props,
320 324
                                              String tableIndexes, 
321 325
                                              String xmlns,
322 326
                                              String xmlPrefix)
323 327
   {
324
      TempTableBuilder ttb = new TempTableBuilder();
325
      props.forEachRemaining(ttb::addNewField);
326
      
327
      if (tableIndexes != null)
328
      {
329
         String[] indexes = tableIndexes.split("\\.");
330
         for (int i = 0; i < indexes.length; i++)
331
         {
332
            String indexDef = indexes[i];
333
            if (indexDef.isEmpty())
334
            {
335
               continue;
336
            }
337
            String[] compAndName = indexDef.split(":");
338
            String typeAndComps = compAndName[0];
339
            String idxName = compAndName[1];
340
            String[] comps = typeAndComps.split(",");
341
            boolean unique = (i != 0) || "1".equals(comps[0]);
342
            boolean primary = (i == 0) && ("1".equals(comps[0]) || "0".equals(comps[0]));
343
            
344
            ttb.addNewIndex(new character(idxName),
345
                            new logical(unique),
346
                            new logical(primary));
347
            for (int j = (primary ? 1 : 0); j < comps.length; j++)
348
            {
349
               ttb.addFieldToIndex(idxName, comps[j]);
350
            }
351
         }
352
      }
353
      
354
      ttb.tempTablePrepare(tableName);
355
      BufferImpl buff = (BufferImpl) ttb.defaultBufferHandle().getResource();
356
      if (xmlns != null)
357
      {
358
         buff.namespaceURI(xmlns);
359
      }
360
      if (xmlPrefix != null)
361
      {
362
         buff.namespacePrefix(xmlPrefix);
363
      }
364
      
365
      return buff;
328
      return createTable(tableName, props, 
329
               () -> parseIndexString(tableIndexes), xmlns, xmlPrefix);
330
   }
331
   
332
   /**
333
    * Create a temp-table with the specified definition, as received from a remote side.
334
    * 
335
    * @param    tableName
336
    *           The table name.
337
    * @param    props
338
    *           The property definitions.
339
    * @param    indexProvider
340
    *           indexes' provider.
341
    * @param    xmlns
342
    *           The XML namespace.
343
    * @param    xmlPrefix
344
    *           The XML prefix.
345
    * @return   default buffer for the table
346
    */
347
   public BufferImpl createRemoteTable(String tableName,
348
                                              Iterator<PropertyDefinition> props,
349
                                              Runnable indexProvider, 
350
                                              String xmlns,
351
                                              String xmlPrefix)
352
   {
353
      return createTable(tableName, props, indexProvider, xmlns, xmlPrefix);
366 354
   }
367 355
   
368 356
   /**
......
1341 1329
                              character    label,
1342 1330
                              character    columnLabel)
1343 1331
   {
1332
      return addNewField(name, type, extent, format, initial, label, columnLabel,
1333
               null, null, null, false, false);
1334
   }
1335
   /**
1336
    * Adds a field with the specified properties to the temp-table.
1337
    * This method is the P2J equivalent of <code>ADD-NEW-FIELD</code> method
1338
    * of Progress 4GL.
1339
    * <p>
1340
    * When a parameter is set to null, it means it was not specified by the business logic.
1341
    *
1342
    * @param   name
1343
    *          The name of the field to be created in the temp-table.
1344
    * @param   type
1345
    *          The data type of the specified field.
1346
    * @param   extent
1347
    *          An integer expression specifying the extent of an array.
1348
    * @param   format
1349
    *          The data format for the defined data type. If empty or unknown, format is
1350
    *          replaced with default format. Null value means that format is not used in
1351
    *          ADD-NEW-FIELD.
1352
    * @param   initial
1353
    *          An expression that evaluates to the initial value of the defined field.
1354
    *          TODO: this method will probably be overloaded because of this.
1355
    * @param   label
1356
    *          The label of the defined field. If <code>null</code> or unknown the name
1357
    *          parameter will be used.
1358
    * @param   columnLabel
1359
    *          The label of the column associated with the defined field
1360
    * @param   help 
1361
    * @param   xmlNodeType 
1362
    * @param   codePage 
1363
    * @param   serializeHidden 
1364
    * @param   caseSensitive 
1365
    *
1366
    * @return  <code>true</code> on success.
1367
    */
1368
   public logical addNewField(character    name,
1369
                              character    type,
1370
                              integer      extent,
1371
                              character    format,
1372
                              BaseDataType initial,
1373
                              character    label,
1374
                              character    columnLabel,
1375
                              character    help,
1376
                              character    xmlNodeType,
1377
                              character    codePage,
1378
                              boolean      serializeHidden,
1379
                              boolean      caseSensitive)
1380
   {
1344 1381
      addFunctionCalled = true;
1345 1382
      
1346 1383
      if (_prepared())
......
1398 1435
      
1399 1436
      String labelStr = label != null ? label.getValue() : null;
1400 1437
      String columnLabelStr = columnLabel != null ? columnLabel.getValue() : null;
1438
      String helpStr = help != null ? help.getValue() : null;
1439
      String codePageStr = codePage != null ? codePage.getValue() : null;
1440
      String xmlNodeTypeStr = xmlNodeType != null ? xmlNodeType.getValue() : null;
1401 1441
      
1402 1442
      // Note: case-sensitivity and CLOB code page cannot be specified using P4GL ADD-NEW-FIELD method
1403 1443
      long ext = extent == null || extent.getValue() == 1 ? 0 : extent.getValue();
1404 1444
      P2JField field = new P2JField(fieldName, parmType, ext, formatStr,
1405
                                    initial, labelStr, columnLabelStr, false, null, null, false, null, null,
1406
                                    null, null, false, 0, 0);
1445
                                    initial, labelStr, columnLabelStr, caseSensitive, 
1446
                                    codePageStr, helpStr, serializeHidden, null, null,
1447
                                    null, xmlNodeTypeStr, false, 0, 0);
1407 1448
      addField(field);
1408 1449
      return new logical(true);
1409 1450
   }
......
2733 2774
   }
2734 2775
   
2735 2776
   /**
2777
    * Create a temp-table with the specified definition.
2778
    * 
2779
    * @param    tableName
2780
    *           The table name.
2781
    * @param    props
2782
    *           The property definitions.
2783
    * @param    tableIndexes
2784
    *           The index definitions.
2785
    * @param    xmlns
2786
    *           The XML namespace.
2787
    * @param    xmlPrefix
2788
    *           The XML prefix.
2789
    * @return   default buffer for the table
2790
    */
2791
   public BufferImpl createTable(String tableName,
2792
                                 Iterator<PropertyDefinition> props,
... This diff was truncated because it exceeds the maximum size that can be displayed.