001    // Copyright (c) 2001 Hursh Jain (http://www.mollypages.org) 
002    // The Molly framework is freely distributable under the terms of an
003    // MIT-style license. For details, see the molly pages web site at:
004    // http://www.mollypages.org/. Use, modify, have fun !
005    
006    package fc.jdbc.dbo.generated;
007    
008    /*
009     * Auto generated on: Wed May 13 01:41:13 EDT 2020
010     * JDBC url: [jdbc:postgresql://127.0.0.1/test]
011     * WARNING: Manual edits will be lost if/when this file is regenerated.
012     */
013    import java.io.*;
014    import java.math.*;
015    import java.sql.*;
016    import java.util.*;
017    
018    import fc.io.*;
019    import fc.jdbc.*;
020    import fc.jdbc.dbo.*;
021    import fc.util.*;
022    import fc.web.forms.*;
023    
024    /**
025    Manages various operations on the alltypes table. 
026    
027    <p>Most methods of this class take a {@link java.sql.Connection Connection} as an argument
028    and use that connection to run various queries. The connection parameter is never closed
029    by methods in this class and that connection can and should be used again. Methods of this
030    class will also throw a <tt>IllegalArgumentException</tt> if the specified connection
031    object is <tt>null</tt>.
032    
033    <p>Thread Safety: Operations on this class are by and large thread safe in that multiple
034    threads can call the methods at the same time. However, seperate threads should use
035    seperate connection objects when invoking methods of this class.
036    */
037    public final class alltypesMgr extends fc.jdbc.dbo.DBOMgr
038    {
039    /* --- Fields used for collecting usage statistics --- 
040    Increments to these don't need to be synchronized since these are
041    ints and not longs and memory visibility is not an issue in the
042    toString() method (in which these are read).
043    */
044    private static int __getall_called = 0;
045    private static int __getlimited_called = 0;
046    private static int __getbykey_called = 0;
047    private static int __getwhere_called = 0;
048    private static int __getusing_called = 0;
049    private static int __getusing_ps_called = 0;
050    private static int __getfromrs_called = 0;
051    private static int __save_called = 0;
052    private static int __delete_called = 0;
053    private static int __deletebykey_called = 0;
054    private static int __deletewhere_called = 0;
055    private static int __deleteusing_called = 0;
056    private static int __count_called = 0;
057    private static int __countwhere_called = 0;
058    private static int __countusing_called = 0;
059    private static int __exists_called = 0;
060    /* -------------- end statistics fields -------------- */
061    
062    /** Constructor is private since class is never instantiated */
063    private alltypesMgr() {
064      }
065    
066    
067    static private final String getAllStmt = "SELECT id, smallint_val, int_val, bigint_val, float_val, double_val, numeric_val, char_val, varchar_val, longvarchar_val, date_val, time_val, timestamp_val, bit_val, array_val, boolean_val, varbinary_val, json_val, jsonb_val from alltypes";
068    /** 
069    Returns all rows in the table. Use with care for large tables since
070    this method can result in VM out of memory errors. <p>This method
071    also takes an optional (can be null) <tt>clause</tt> parameter which
072    is sent as is to the database. For example, a clause can be:
073    <blockquote><pre>
074    order by some_column_name
075    </pre> </blockquote>
076    @return   a list containing {@link alltypes } objects <i>or an empty list</i> if there are no rows in the database*/
077    public static List getAll(final Connection con, final String clause) throws SQLException
078      {
079      __getall_called++;
080      final List list = new ArrayList();
081      final String getAllStmtClaused = (clause == null) ? 
082                   getAllStmt : getAllStmt + " " + clause;
083      PreparedStatement ps = prepareStatement(con, getAllStmtClaused);
084      log.bug("Query to run: ", ps);
085      final ResultSet rs = ps.executeQuery();
086      while (true) {
087        alltypes bean = decodeFromRS(rs);
088        if (bean == null) { break; } 
089        list.add(bean);
090        }
091      rs.close();
092      return list;
093      }
094    
095    /** 
096    Convenience method that invokes {@link getAll(Connection, alltypes, String) getAll} with an empty additional clause.
097    */
098    public static List getAll(final Connection con) throws ValidateException, SQLException
099      {
100      return getAll(con, null);
101      }
102    
103    static private final String getLimitedStmt = "SELECT id, smallint_val, int_val, bigint_val, float_val, double_val, numeric_val, char_val, varchar_val, longvarchar_val, date_val, time_val, timestamp_val, bit_val, array_val, boolean_val, varbinary_val, json_val, jsonb_val from alltypes";
104    /** 
105    Returns all rows in the table starting from some row number and limited
106    by a certain number of rows after that starting row. 
107    <p>
108    This method takes a required (non-null) <code>order_clause</code>, since when using
109    a limit clause, rows must be ordered for the limit to make sense. The
110    clause should be of the form <font color=blue>order by ...</font>
111    <p>
112    The <code>limit</code> specifies the number of rows that will be returned. (those many
113    or possibly lesser rows will be returned, if the query itself yields less
114    rows).
115    <p>
116    The <code>offset</code> skips that many rows before returning rows. A zero offset is
117    the same as a traditional query with no offset clause, where rows from
118    the beginning are returned. If say, offset = 10, then rows starting from
119    row 11 will be returned.
120    <p>
121    The sql-query generated by this method is database specific but will (typically) look like:
122    <blockquote><pre>
123    select &lt;column_list&gt; from &lt;table&gt; order by &lt;clause&gt; limit 5 offset 10
124    </pre> </blockquote>
125    @return   a list containing {@link alltypes } objects <i>or an empty list</i> if there are no rows in the database*/
126    public static List getLimited(final Connection con, final String order_clause, int limit, int offset) throws SQLException
127      {
128      __getlimited_called++;
129      final List list = new ArrayList();
130      final String tmp = getLimitedStmt + " " + order_clause + " LIMIT " + limit + " OFFSET " + offset;
131      PreparedStatement ps = prepareStatement(con, tmp);
132      log.bug("Query to run: ", ps);
133      final ResultSet rs = ps.executeQuery();
134      while (true) {
135        alltypes bean = decodeFromRS(rs);
136        if (bean == null) { break; } 
137        list.add(bean);
138        }
139      rs.close();
140      return list;
141      }
142    
143    static private final String getByPKStmt = "SELECT id, smallint_val, int_val, bigint_val, float_val, double_val, numeric_val, char_val, varchar_val, longvarchar_val, date_val, time_val, timestamp_val, bit_val, array_val, boolean_val, varbinary_val, json_val, jsonb_val from alltypes WHERE id=?";
144    /** 
145    Returns <b>the</b> row corresponding to the specified primary key(s) of this table 
146    or <b><tt>null</tt></b> if no row was found.
147    <p>This method uses a prepared statement and is safe from SQL injection attacks
148    */
149    public static alltypes getByKey(final Connection con, int id) throws SQLException
150      {
151      __getbykey_called++;
152      PreparedStatement ps = prepareStatement(con, getByPKStmt);
153      StringBuilder errbuf = null;
154    
155      //id [int] is primitive, skipping null test
156      ps.setInt(1, id); 
157      
158      if (errbuf != null) {
159        throw new ValidateException(errbuf.toString());
160        }
161      final ResultSet rs = ps.executeQuery();
162      log.bug("Query to run: ", ps);
163      alltypes bean = decodeFromRS(rs);
164      rs.close();
165      return bean;
166      }
167    
168    /** 
169    Returns the rows returned by querying the table with the specified
170    <tt>WHERE</tt> clause or <i>an empty list</i> if no rows were found.
171    (note: the string <tt>"WHERE"</tt> does <b>not</b> have to be
172    specified in the clause. It is added automatically by this method).
173    <p>Queries can use database functions such as: <code>lower()</code>,
174    <code>upper()</code>, <code>LIKE</code> etc. For example:
175    <pre><blockquote>alltypesMgr.getWhere("lower(col_a) = 'foo'")
176    //compares the lower case value of col_a with the string 'foo'
177    </blockquote></pre>
178    <p><b>The "where" clause is sent as-is to the database</b>. SQL
179    injection attacks are possible if it is created as-is from a <b><u>untrusted</u></b> source.
180    
181    @throws IllegalArgumentException if the specified <tt>where</tt> parameter is null
182    */
183    public static List getWhere(final Connection con, final String where) throws SQLException
184      {
185      __getwhere_called++;
186      Argcheck.notnull(where, "the where parameter was null (and should not be null)");
187      final String where_stmt = "SELECT id, smallint_val, int_val, bigint_val, float_val, double_val, numeric_val, char_val, varchar_val, longvarchar_val, date_val, time_val, timestamp_val, bit_val, array_val, boolean_val, varbinary_val, json_val, jsonb_val from alltypes WHERE " + where ;
188      Statement stmt = QueryUtil.getRewindableStmt(con);
189      log.bug("Query to run: ", stmt, " ", where_stmt);
190      final List list = new ArrayList();
191      final ResultSet rs = stmt.executeQuery(where_stmt);
192      while (true) {
193        alltypes bean = decodeFromRS(rs);
194        if (bean == null) { break; } 
195        list.add(bean);
196        }
197      stmt.close();
198      return list;
199      }
200    
201    /** 
202    Returns the rows returned by querying the table with the value of the
203    specified <tt>alltypes</tt> object or <i>an empty list</i> if no rows were found. As many
204    fields in <tt>alltypes</tt> can be set as needed and the values of
205    all set fields (including fields explicitly set to <tt>null</tt>)
206    are then used to perform the query.
207    <p>
208    This method is often convenient/safer than the {@link #getWhere
209    getWhere} method (because the <tt>getWhere</tt> method takes an
210    arbitrary query string which has to be properly escaped by the
211    user).
212    <p>Essentially, this method is a more convenient way to use a
213    PreparedStatement. Internally, a prepared statement is created and
214    it's parameters are set to fields that are set in this object).
215    Using PreparedStatements directly is also perfectly fine. For
216    example, the following are equivalent. 
217    <p> Using a PreparedStatement:
218    <blockquote><pre>
219    String foo = "select * from table_foo where x = ? and y = ?";
220    PreparedStatement ps = con.prepareStatement(foo);
221    ps.setString(1, "somevalue");
222    ps.setString(2, "othervalue");
223    ResultSet rs  = ps.executeUpdate();
224    while (rs.next()) {
225        table_foo bean = table_fooMgr.getFromRS(rs);
226        }
227    </pre> </blockquote>
228    
229    Using this method:
230    <blockquote><pre>
231    table_foo <font color=blue>proto</font> = new table_foo();
232    proto.set_x("somevalue"); //compile time safety
233    proto.set_y("othervalue");  //compile time safety
234    List beans = table_fooMgr.<font color=blue>getUsing(proto)</font>;
235    </pre> </blockquote>
236    <p>This method also takes an <tt>clause</tt> parameter which
237    is sent as is to the database. For example, a clause can be:
238    <blockquote><pre>
239    List beans = table_fooMgr.<font color=blue>getUsing(proto, <b>"order by some_column_name"</b>)</font>;
240    </pre> </blockquote>
241    This clause is optional. Specify <tt>null</tt> to not use it at all.
242    If the clause is specified, do <font size='+1'><b>NOT</b></font> include the word <tt>WHERE</tt>.
243    
244    The fields that are set in the proto object (as shown above) are sent as
245    part of a WHERE clause constructed internally. If you are specifying a clause
246    as well, you should not specify the word <tt>WHERE</tt>. However, you may have
247    to specify <tt>AND</tt> to add to the internal WHERE clause, if you have set any
248    fields in the proto object. For example
249    <blockquote><pre>
250    List beans = table_fooMgr.<font color=blue>getUsing(proto, <b>"and bar = 5"</b>)</font>;
251    </pre> </blockquote>
252    <p>Note: For a <i>very</i> large number of rows, it may be more
253    efficient to use a prepared statement directly (as opposed to using
254    this method). In most cases, this is not something to worry about,
255    but your mileage may vary...
256    */
257    public static List getUsing(final Connection con, final alltypes bean, final String clause) throws ValidateException, SQLException
258      {
259      __getusing_called++;
260      Argcheck.notnull(bean, "the bean parameter was null (and should not be null)");
261      if (! bean.isModified()) { 
262        throw new ValidateException("bean=" + bean + " not modified, ignoring query");
263        }
264    
265      int __count = 0;
266      final StringBuilder buf = new StringBuilder(512);
267      buf.append("SELECT id, smallint_val, int_val, bigint_val, float_val, double_val, numeric_val, char_val, varchar_val, longvarchar_val, date_val, time_val, timestamp_val, bit_val, array_val, boolean_val, varbinary_val, json_val, jsonb_val from alltypes WHERE ");
268      if (bean.isModified_id()) { 
269        buf.append("id=? and ");
270        __count++;
271        }
272      if (bean.isModified_smallint_val()) { 
273        if (bean.isModifiedSetNull_smallint_val()) {
274          buf.append("smallint_val is NULL and ");
275          }
276        else{
277          buf.append("smallint_val=? and ");
278          __count++;
279          }
280        }
281      if (bean.isModified_int_val()) { 
282        buf.append("int_val=? and ");
283        __count++;
284        }
285      if (bean.isModified_bigint_val()) { 
286        if (bean.isModifiedSetNull_bigint_val()) {
287          buf.append("bigint_val is NULL and ");
288          }
289        else{
290          buf.append("bigint_val=? and ");
291          __count++;
292          }
293        }
294      if (bean.isModified_float_val()) { 
295        if (bean.isModifiedSetNull_float_val()) {
296          buf.append("float_val is NULL and ");
297          }
298        else{
299          buf.append("float_val=? and ");
300          __count++;
301          }
302        }
303      if (bean.isModified_double_val()) { 
304        if (bean.isModifiedSetNull_double_val()) {
305          buf.append("double_val is NULL and ");
306          }
307        else{
308          buf.append("double_val=? and ");
309          __count++;
310          }
311        }
312      if (bean.isModified_numeric_val()) { 
313        if (bean.get_numeric_val() == null) {
314          buf.append("numeric_val is NULL and ");
315          }
316        else{
317          buf.append("numeric_val=? and ");
318          __count++;
319          }
320        }
321      if (bean.isModified_char_val()) { 
322        if (bean.get_char_val() == null) {
323          buf.append("char_val is NULL and ");
324          }
325        else{
326          buf.append("char_val=? and ");
327          __count++;
328          }
329        }
330      if (bean.isModified_varchar_val()) { 
331        if (bean.get_varchar_val() == null) {
332          buf.append("varchar_val is NULL and ");
333          }
334        else{
335          buf.append("varchar_val=? and ");
336          __count++;
337          }
338        }
339      if (bean.isModified_longvarchar_val()) { 
340        if (bean.get_longvarchar_val() == null) {
341          buf.append("longvarchar_val is NULL and ");
342          }
343        else{
344          buf.append("longvarchar_val=? and ");
345          __count++;
346          }
347        }
348      if (bean.isModified_date_val()) { 
349        if (bean.get_date_val() == null) {
350          buf.append("date_val is NULL and ");
351          }
352        else{
353          buf.append("date_val=? and ");
354          __count++;
355          }
356        }
357      if (bean.isModified_time_val()) { 
358        if (bean.get_time_val() == null) {
359          buf.append("time_val is NULL and ");
360          }
361        else{
362          buf.append("time_val=? and ");
363          __count++;
364          }
365        }
366      if (bean.isModified_timestamp_val()) { 
367        if (bean.get_timestamp_val() == null) {
368          buf.append("timestamp_val is NULL and ");
369          }
370        else{
371          buf.append("timestamp_val=? and ");
372          __count++;
373          }
374        }
375      if (bean.isModified_bit_val()) { 
376        if (bean.get_bit_val() == null) {
377          buf.append("bit_val is NULL and ");
378          }
379        else{
380          buf.append("bit_val=? and ");
381          __count++;
382          }
383        }
384      if (bean.isModified_array_val()) { 
385        if (bean.get_array_val() == null) {
386          buf.append("array_val is NULL and ");
387          }
388        else{
389          buf.append("array_val=? and ");
390          __count++;
391          }
392        }
393      if (bean.isModified_boolean_val()) { 
394        if (bean.get_boolean_val() == null) {
395          buf.append("boolean_val is NULL and ");
396          }
397        else{
398          buf.append("boolean_val=? and ");
399          __count++;
400          }
401        }
402      if (bean.isModified_varbinary_val()) { 
403        if (bean.get_varbinary_val() == null) {
404          buf.append("varbinary_val is NULL and ");
405          }
406        else{
407          buf.append("varbinary_val=? and ");
408          __count++;
409          }
410        }
411      if (bean.isModified_json_val()) { 
412        if (bean.get_json_val() == null) {
413          buf.append("json_val is NULL and ");
414          }
415        else{
416          buf.append("json_val=? and ");
417          __count++;
418          }
419        }
420      if (bean.isModified_jsonb_val()) { 
421        if (bean.get_jsonb_val() == null) {
422          buf.append("jsonb_val is NULL and ");
423          }
424        else{
425          buf.append("jsonb_val=? and ");
426          __count++;
427          }
428        }
429    
430      buf.setLength(buf.length() - 4);
431    
432      if (clause != null) {
433        buf.append(" ");
434        buf.append(clause);
435        }
436    
437      final String getUsingPKStmt = buf.toString();
438      PreparedStatement ps = prepareStatement(con, getUsingPKStmt);
439      int pos = 0;
440      if (bean.isModified_id()) {
441          pos++;
442          int id = bean.get_id();
443          ps.setInt(pos, id); 
444          }
445      if (bean.isModified_smallint_val()) {
446        if (bean.isModifiedSetNull_smallint_val()) { 
447          /* no value to set here, uses [xxx IS NULL] syntax*/
448          }
449        else{
450          pos++;
451          short smallint_val = bean.get_smallint_val();
452          ps.setShort(pos, smallint_val); 
453          }
454        }
455      if (bean.isModified_int_val()) {
456          pos++;
457          int int_val = bean.get_int_val();
458          ps.setInt(pos, int_val); 
459          }
460      if (bean.isModified_bigint_val()) {
461        if (bean.isModifiedSetNull_bigint_val()) { 
462          /* no value to set here, uses [xxx IS NULL] syntax*/
463          }
464        else{
465          pos++;
466          long bigint_val = bean.get_bigint_val();
467          ps.setLong(pos, bigint_val); 
468          }
469        }
470      if (bean.isModified_float_val()) {
471        if (bean.isModifiedSetNull_float_val()) { 
472          /* no value to set here, uses [xxx IS NULL] syntax*/
473          }
474        else{
475          pos++;
476          float float_val = bean.get_float_val();
477          ps.setFloat(pos, float_val); 
478          }
479        }
480      if (bean.isModified_double_val()) {
481        if (bean.isModifiedSetNull_double_val()) { 
482          /* no value to set here, uses [xxx IS NULL] syntax*/
483          }
484        else{
485          pos++;
486          double double_val = bean.get_double_val();
487          ps.setDouble(pos, double_val); 
488          }
489        }
490      if (bean.isModified_numeric_val()) {
491        if (bean.get_numeric_val() == null) { 
492          /* no value to set here, uses [xxx IS NULL] syntax*/
493          }
494        else{
495          pos++;
496          BigDecimal numeric_val = bean.get_numeric_val();
497          ps.setBigDecimal(pos, numeric_val); 
498          }
499        }
500      if (bean.isModified_char_val()) {
501        if (bean.get_char_val() == null) { 
502          /* no value to set here, uses [xxx IS NULL] syntax*/
503          }
504        else{
505          pos++;
506          String char_val = bean.get_char_val();
507          ps.setString(pos, char_val); 
508          }
509        }
510      if (bean.isModified_varchar_val()) {
511        if (bean.get_varchar_val() == null) { 
512          /* no value to set here, uses [xxx IS NULL] syntax*/
513          }
514        else{
515          pos++;
516          String varchar_val = bean.get_varchar_val();
517          ps.setString(pos, varchar_val); 
518          }
519        }
520      if (bean.isModified_longvarchar_val()) {
521        if (bean.get_longvarchar_val() == null) { 
522          /* no value to set here, uses [xxx IS NULL] syntax*/
523          }
524        else{
525          pos++;
526          String longvarchar_val = bean.get_longvarchar_val();
527          ps.setString(pos, longvarchar_val); 
528          }
529        }
530      if (bean.isModified_date_val()) {
531        if (bean.get_date_val() == null) { 
532          /* no value to set here, uses [xxx IS NULL] syntax*/
533          }
534        else{
535          pos++;
536          java.sql.Date date_val = bean.get_date_val();
537          ps.setDate(pos, date_val); 
538          }
539        }
540      if (bean.isModified_time_val()) {
541        if (bean.get_time_val() == null) { 
542          /* no value to set here, uses [xxx IS NULL] syntax*/
543          }
544        else{
545          pos++;
546          Time time_val = bean.get_time_val();
547          ps.setTime(pos, time_val); 
548          }
549        }
550      if (bean.isModified_timestamp_val()) {
551        if (bean.get_timestamp_val() == null) { 
552          /* no value to set here, uses [xxx IS NULL] syntax*/
553          }
554        else{
555          pos++;
556          Timestamp timestamp_val = bean.get_timestamp_val();
557          ps.setTimestamp(pos, timestamp_val); 
558          }
559        }
560      if (bean.isModified_bit_val()) {
561        if (bean.get_bit_val() == null) { 
562          /* no value to set here, uses [xxx IS NULL] syntax*/
563          }
564        else{
565          pos++;
566          Boolean bit_val = bean.get_bit_val();
567          ps.setObject(pos, bit_val); 
568          }
569        }
570      if (bean.isModified_array_val()) {
571        if (bean.get_array_val() == null) { 
572          /* no value to set here, uses [xxx IS NULL] syntax*/
573          }
574        else{
575          pos++;
576          java.sql.Array array_val = bean.get_array_val();
577          ps.setArray(pos, array_val); 
578          }
579        }
580      if (bean.isModified_boolean_val()) {
581        if (bean.get_boolean_val() == null) { 
582          /* no value to set here, uses [xxx IS NULL] syntax*/
583          }
584        else{
585          pos++;
586          Boolean boolean_val = bean.get_boolean_val();
587          ps.setObject(pos, boolean_val); 
588          }
589        }
590      if (bean.isModified_varbinary_val()) {
591        if (bean.get_varbinary_val() == null) { 
592          /* no value to set here, uses [xxx IS NULL] syntax*/
593          }
594        else{
595          pos++;
596          byte[] varbinary_val = bean.get_varbinary_val();
597          ps.setBytes(pos, varbinary_val); 
598          }
599        }
600      if (bean.isModified_json_val()) {
601        if (bean.get_json_val() == null) { 
602          /* no value to set here, uses [xxx IS NULL] syntax*/
603          }
604        else{
605          pos++;
606          String json_val = bean.get_json_val();
607          ps.setObject(pos, json_val, java.sql.Types.OTHER); 
608          }
609        }
610      if (bean.isModified_jsonb_val()) {
611        if (bean.get_jsonb_val() == null) { 
612          /* no value to set here, uses [xxx IS NULL] syntax*/
613          }
614        else{
615          pos++;
616          String jsonb_val = bean.get_jsonb_val();
617          ps.setObject(pos, jsonb_val, java.sql.Types.OTHER); 
618          }
619        }
620      log.bug("Query to run: ", ps);
621      final List list = new ArrayList();
622      final ResultSet rs = ps.executeQuery();
623      while (true) {
624        alltypes row = decodeFromRS(rs);
625        if (row == null) { break; } 
626        list.add(row);
627        }
628      rs.close();
629      return list;
630      }
631    
632    /** 
633    Convenience method that invokes {@link getUsing(Connection, alltypes, String) getUsing} with an empty <i><tt>clause</tt></i> parameter.*/
634    public static List getUsing(final Connection con, final alltypes bean) throws ValidateException, SQLException
635      {
636      return getUsing(con, bean, null);
637      }
638    
639    /**
640    This is a <i>convenience</i> method that runs the specified 
641    prepared statement to perform an arbitrary query. For example: 
642    <blockquote>
643    <pre>
644    PreparedStatement <font color=blue>ps</font> = con.prepareStatement(
645        "select * from some_table where some_column = ?");
646    ps.setString(1, "foo");
647    List list = fooMgr.<font color=blue>getUsing</font>(con, <font color=blue>ps</font>);
648    for (int n = 0; n < list.size(); n++) {
649      sometable t = (sometable) list.get(n);
650      //do something
651      }
652    </pre>
653    </blockquote>
654    The effect of the above is <u>equivalent</u> to the following (larger) block 
655    of code:
656    <blockquote>
657    <pre>
658    PreparedStatement <font color=blue>ps</font> = con.prepareStatement(
659      "select * from sometable where some_column = ?"
660      );
661    ps.setString(1, "foo");
662    ResultSet rs = <font color=blue>ps.executeQuery()</font>;
663    List list = new ArrayList();
664    while (rs.next()) {
665      list.add(sometableMgr.<font color=blue>getFromRS(rs)</font>);
666      }
667    
668    for (int n = 0; n < list.size(); n++) {
669      sometable t = (sometable) list.get(n);
670      //do something
671      }
672    </pre>
673    </blockquote>
674    
675    Note: Just as with other get<i>XXX</i> methods, for large amounts of
676    rows (say many thousands), it may be more efficient use and iterate
677    through a JDBC result set directly.
678    */
679    public static List getUsing(final Connection con,  final PreparedStatement ps) throws ValidateException, SQLException
680      {
681      __getusing_ps_called++;
682      log.bug("Query to run: ", ps);
683      final List list = new ArrayList();
684      final ResultSet rs = ps.executeQuery();
685      while (true) {
686        alltypes row = decodeFromRS(rs);
687        if (row == null) { break; } 
688        list.add(row);
689        }
690      rs.close();
691      return list;
692      }
693    
694    /**
695    This is a <i>convenience</i> method that runs the specified 
696    {@link fc.jdbc.dbo.NamedParamStatement NamedParamStatement} to perform an arbitrary query.
697    For example: <blockquote>
698    <pre>
699    NamedParamStatement <font color=blue>ps</font> = queryReadeer.getQuery("somequery");
700    ps.setString("some_placeholder", "foo");
701    List list = fooMgr.<font color=blue>getUsing</font>(con, <font color=blue>ps</font>);
702    for (int n = 0; n < list.size(); n++) {
703      sometable t = (sometable) list.get(n);
704      //do something
705      }
706    </pre>
707    </blockquote>
708    
709    Note: Just as with other get<i>XXX</i> methods, for large amounts of
710    rows (say many thousands), it may be more efficient use and iterate
711    through a JDBC result set directly.
712    */
713    public static List getUsing(final Connection con,  final NamedParamStatement ps) throws ValidateException, SQLException
714      {
715      __getusing_ps_called++;
716      log.bug("Query to run: ", ps);
717      final List list = new ArrayList();
718      final ResultSet rs = ps.executeQuery();
719      while (true) {
720        alltypes row = decodeFromRS(rs);
721        if (row == null) { break; } 
722        list.add(row);
723        }
724      rs.close();
725      return list;
726      }
727    
728    /** 
729    Returns a <i>comma delimited list</i> of <i>all</i> columns in <tt>alltypes</tt>. These column names are fully qualified, i.e., they contain 
730    table name as a prefix to the column name. For example:
731    <blockquote><pre>
732    <tt>tablename.column1 AS tablename_column1, tablename.column2 AS tablename_column2 ...</tt>
733    </pre></blockquote>
734    <p>This list is suitable for placing in the column(s) clause of a select query, such as: 
735    <blockquote>
736    <tt>Single table: select <i><font color=blue>[column_list_A]</font></i> from table_A</tt><br>
737    <tt>Join: select <i><font color=blue>[column_list_A], [column_list_B]</font></i> from table_A, table_B</tt>
738    </blockquote>
739    The ResultSet returned by the query can be used directly or can be passed
740    to the {@link #getFromRS getFromRS} method to convert it into a list of <code>alltypes
741    </code> objects. If the query is a join across multiple tables,
742    then the {@link #getFromRS getFromRS} method for each table manager
743    can be called on the same ResultSet to retrieve the row object for
744    that table.
745    Note: the returned list of names has a trailing space, which is good when
746    the rest of the query is appended to this list.
747    */
748    public static String columns() throws SQLException
749      {
750      return "alltypes.id as alltypes_id, alltypes.smallint_val as alltypes_smallint_val, alltypes.int_val as alltypes_int_val, alltypes.bigint_val as alltypes_bigint_val, alltypes.float_val as alltypes_float_val, alltypes.double_val as alltypes_double_val, alltypes.numeric_val as alltypes_numeric_val, alltypes.char_val as alltypes_char_val, alltypes.varchar_val as alltypes_varchar_val, alltypes.longvarchar_val as alltypes_longvarchar_val, alltypes.date_val as alltypes_date_val, alltypes.time_val as alltypes_time_val, alltypes.timestamp_val as alltypes_timestamp_val, alltypes.bit_val as alltypes_bit_val, alltypes.array_val as alltypes_array_val, alltypes.boolean_val as alltypes_boolean_val, alltypes.varbinary_val as alltypes_varbinary_val, alltypes.json_val as alltypes_json_val, alltypes.jsonb_val as alltypes_jsonb_val ";
751      }
752    
753    /** 
754    Returns a <i>comma delimited list</i> of <i>all</i> columns in <tt>alltypes</tt>. These column names are prefix with the specified prefix, which corresponds to the
755    table abbreviation used in the "AS" clause. For example:
756    <blockquote><pre>
757    <tt>xyz.column1 AS xyz_column1, xyz.column2 AS xyz_column2 ...</tt>
758    </pre></blockquote>
759    <p>This list is suitable for placing in the column(s) clause of a select query, such as: 
760    <blockquote>
761    <p><b>Note:</b> the "." will automatically be appended between the prefix and column name
762    so the prefix should not end with a "." or "_", etc<p>
763    <tt>Single table: select <i><font color=blue>[column_list_A]</font></i> from table_A <b>AS</b> xyz</tt><br>
764    <tt>Join: select <i><font color=blue>[column_list_A], [column_list_B]</font></i> from table_A <b>AS</b> xyz, table_B <b>AS</b> zzz</tt>
765    </blockquote>
766    The ResultSet returned by the query can be used directly or can be passed
767    to the {@link #getFromRS getFromRS(String)} method to convert it into a list of <code>alltypes
768    </code> objects. If the query is a join across multiple tables,
769    then the {@link #getFromRS getFromRS(String)} method for each table manager
770    can be called on the same ResultSet to retrieve the row object for
771    that table.
772    Note: the returned list of names has a trailing space, which is good when
773    the rest of the query is appended to this list.
774    */
775    public static String columns(String prefix) throws SQLException
776      {
777      final StringBuffer buf = new StringBuffer(19 * 10);
778    
779      buf.append(prefix);
780      buf.append(".");
781      buf.append("id");
782      buf.append(" as ");
783      buf.append(prefix);
784      buf.append("_");
785      buf.append("id");
786    
787      buf.append(", ");
788      buf.append(prefix);
789      buf.append(".");
790      buf.append("smallint_val");
791      buf.append(" as ");
792      buf.append(prefix);
793      buf.append("_");
794      buf.append("smallint_val");
795    
796      buf.append(", ");
797      buf.append(prefix);
798      buf.append(".");
799      buf.append("int_val");
800      buf.append(" as ");
801      buf.append(prefix);
802      buf.append("_");
803      buf.append("int_val");
804    
805      buf.append(", ");
806      buf.append(prefix);
807      buf.append(".");
808      buf.append("bigint_val");
809      buf.append(" as ");
810      buf.append(prefix);
811      buf.append("_");
812      buf.append("bigint_val");
813    
814      buf.append(", ");
815      buf.append(prefix);
816      buf.append(".");
817      buf.append("float_val");
818      buf.append(" as ");
819      buf.append(prefix);
820      buf.append("_");
821      buf.append("float_val");
822    
823      buf.append(", ");
824      buf.append(prefix);
825      buf.append(".");
826      buf.append("double_val");
827      buf.append(" as ");
828      buf.append(prefix);
829      buf.append("_");
830      buf.append("double_val");
831    
832      buf.append(", ");
833      buf.append(prefix);
834      buf.append(".");
835      buf.append("numeric_val");
836      buf.append(" as ");
837      buf.append(prefix);
838      buf.append("_");
839      buf.append("numeric_val");
840    
841      buf.append(", ");
842      buf.append(prefix);
843      buf.append(".");
844      buf.append("char_val");
845      buf.append(" as ");
846      buf.append(prefix);
847      buf.append("_");
848      buf.append("char_val");
849    
850      buf.append(", ");
851      buf.append(prefix);
852      buf.append(".");
853      buf.append("varchar_val");
854      buf.append(" as ");
855      buf.append(prefix);
856      buf.append("_");
857      buf.append("varchar_val");
858    
859      buf.append(", ");
860      buf.append(prefix);
861      buf.append(".");
862      buf.append("longvarchar_val");
863      buf.append(" as ");
864      buf.append(prefix);
865      buf.append("_");
866      buf.append("longvarchar_val");
867    
868      buf.append(", ");
869      buf.append(prefix);
870      buf.append(".");
871      buf.append("date_val");
872      buf.append(" as ");
873      buf.append(prefix);
874      buf.append("_");
875      buf.append("date_val");
876    
877      buf.append(", ");
878      buf.append(prefix);
879      buf.append(".");
880      buf.append("time_val");
881      buf.append(" as ");
882      buf.append(prefix);
883      buf.append("_");
884      buf.append("time_val");
885    
886      buf.append(", ");
887      buf.append(prefix);
888      buf.append(".");
889      buf.append("timestamp_val");
890      buf.append(" as ");
891      buf.append(prefix);
892      buf.append("_");
893      buf.append("timestamp_val");
894    
895      buf.append(", ");
896      buf.append(prefix);
897      buf.append(".");
898      buf.append("bit_val");
899      buf.append(" as ");
900      buf.append(prefix);
901      buf.append("_");
902      buf.append("bit_val");
903    
904      buf.append(", ");
905      buf.append(prefix);
906      buf.append(".");
907      buf.append("array_val");
908      buf.append(" as ");
909      buf.append(prefix);
910      buf.append("_");
911      buf.append("array_val");
912    
913      buf.append(", ");
914      buf.append(prefix);
915      buf.append(".");
916      buf.append("boolean_val");
917      buf.append(" as ");
918      buf.append(prefix);
919      buf.append("_");
920      buf.append("boolean_val");
921    
922      buf.append(", ");
923      buf.append(prefix);
924      buf.append(".");
925      buf.append("varbinary_val");
926      buf.append(" as ");
927      buf.append(prefix);
928      buf.append("_");
929      buf.append("varbinary_val");
930    
931      buf.append(", ");
932      buf.append(prefix);
933      buf.append(".");
934      buf.append("json_val");
935      buf.append(" as ");
936      buf.append(prefix);
937      buf.append("_");
938      buf.append("json_val");
939    
940      buf.append(", ");
941      buf.append(prefix);
942      buf.append(".");
943      buf.append("jsonb_val");
944      buf.append(" as ");
945      buf.append(prefix);
946      buf.append("_");
947      buf.append("jsonb_val");
948      buf.append(" ");
949    
950      return buf.toString();
951    
952      }
953    
954    /** 
955    Creates and returns a new <tt>alltypes</tt> object that represents a row from the specified ResultSet. The ResultSet is
956    typically obtained via a handwritten query/PreparedStatement. The resulting 
957    ResultSet should contain all of the
958    column names of table, and this will only happen if the handwritten query had
959    a select statement that specified all fields or used a <tt>select <b>*</b>..</tt>
960    clause.
961    <p>
962    In the select clause, we could also be selecting multiple tables. To disambiguate
963    between the same field names that may exist in multiple tables, this method 
964    also requires that the query should use <font color=blue>fully qualified</font>
965    (prefixed with the table name) column names, such as:
966    <blockquote><pre>
967    <font color=blue>tablename</font>_column1
968    <font color=blue>tablename</font>_column2
969    ...etc.
970    </pre></blockquote>
971    <p>
972    For example:
973    <blockquote>
974    <code>select <font color=blue>foo</font>.a <b>AS</b> <font color=blue>foo</font>_a, <font color=red>bar</font>.a <b>AS</b> <font color=red>bar</font>_a from <font color=blue>foo</font>, <font color=red>bar</font> where foo.a = bar.a;</code>
975    </blockquote>
976    The {@link #columns} method conveniently returns a list of column names in fully qualified format 
977    and is useful for this purpose.
978    <p>Note: This method will read the <i>current</i> row from the specified result set
979    and will <b>not</b> move the result set pointer to the next row after the current
980    row has been read. The result set should be appropriately positioned [via <tt>rs.next()</tt>]
981    <i>before</i> calling this method.
982    
983    @return a new {@link 
984    alltypes} object populated with the contents of the next    row from the result set or <tt> null </tt> if
985        the ResultSet was empty.
986    */
987    public static alltypes getFromRS(final ResultSet rs) throws SQLException
988      {
989      __getfromrs_called++;
990      Argcheck.notnull(rs, "the specified resultset parameter was null");
991      boolean hasrow = ! rs.isAfterLast();
992      if (! hasrow) { 
993        return null; 
994        } 
995      alltypes bean = new alltypes();
996    
997      bean.set_id( rs.getInt("alltypes_id") );
998      bean.__orig_id = rs.getInt("alltypes_id"); /* save original PK */
999      if (rs.wasNull()) {
1000        bean.__isNullInDB_id = true;
1001        }
1002      bean.set_smallint_val( rs.getShort("alltypes_smallint_val") );
1003      if (rs.wasNull()) {
1004        bean.__isNullInDB_smallint_val = true;
1005        }
1006      bean.set_int_val( rs.getInt("alltypes_int_val") );
1007      if (rs.wasNull()) {
1008        bean.__isNullInDB_int_val = true;
1009        }
1010      bean.set_bigint_val( rs.getLong("alltypes_bigint_val") );
1011      if (rs.wasNull()) {
1012        bean.__isNullInDB_bigint_val = true;
1013        }
1014      bean.set_float_val( rs.getFloat("alltypes_float_val") );
1015      if (rs.wasNull()) {
1016        bean.__isNullInDB_float_val = true;
1017        }
1018      bean.set_double_val( rs.getDouble("alltypes_double_val") );
1019      if (rs.wasNull()) {
1020        bean.__isNullInDB_double_val = true;
1021        }
1022      bean.set_numeric_val( rs.getBigDecimal("alltypes_numeric_val") );
1023      if (rs.wasNull()) {
1024        bean.__isNullInDB_numeric_val = true;
1025        }
1026      bean.set_char_val( rs.getString("alltypes_char_val") );
1027      if (rs.wasNull()) {
1028        bean.__isNullInDB_char_val = true;
1029        }
1030      bean.set_varchar_val( rs.getString("alltypes_varchar_val") );
1031      if (rs.wasNull()) {
1032        bean.__isNullInDB_varchar_val = true;
1033        }
1034      bean.set_longvarchar_val( rs.getString("alltypes_longvarchar_val") );
1035      if (rs.wasNull()) {
1036        bean.__isNullInDB_longvarchar_val = true;
1037        }
1038      bean.set_date_val( rs.getDate("alltypes_date_val") );
1039      if (rs.wasNull()) {
1040        bean.__isNullInDB_date_val = true;
1041        }
1042      bean.set_time_val( rs.getTime("alltypes_time_val") );
1043      if (rs.wasNull()) {
1044        bean.__isNullInDB_time_val = true;
1045        }
1046      bean.set_timestamp_val( rs.getTimestamp("alltypes_timestamp_val") );
1047      if (rs.wasNull()) {
1048        bean.__isNullInDB_timestamp_val = true;
1049        }
1050      bean.set_bit_val( ((Boolean) rs.getObject("alltypes_bit_val")) );
1051      if (rs.wasNull()) {
1052        bean.__isNullInDB_bit_val = true;
1053        }
1054      bean.set_array_val( rs.getArray("alltypes_array_val") );
1055      if (rs.wasNull()) {
1056        bean.__isNullInDB_array_val = true;
1057        }
1058      bean.set_boolean_val( ((Boolean) rs.getObject("alltypes_boolean_val")) );
1059      if (rs.wasNull()) {
1060        bean.__isNullInDB_boolean_val = true;
1061        }
1062      bean.set_varbinary_val( rs.getBytes("alltypes_varbinary_val") );
1063      if (rs.wasNull()) {
1064        bean.__isNullInDB_varbinary_val = true;
1065        }
1066      bean.set_json_val( rs.getString("alltypes_json_val") );
1067      if (rs.wasNull()) {
1068        bean.__isNullInDB_json_val = true;
1069        }
1070      bean.set_jsonb_val( rs.getString("alltypes_jsonb_val") );
1071      if (rs.wasNull()) {
1072        bean.__isNullInDB_jsonb_val = true;
1073        }
1074    
1075      /* set to true when instantiated new, false when we populate the bean from a resultset */
1076      bean.setNew(false);
1077      /* it's not modified, just loaded from the database */
1078      bean.resetModified();
1079      return bean;
1080      }
1081    
1082    /** 
1083    Creates and returns a new <tt>alltypes</tt> object that represents a row from the specified ResultSet. The ResultSet is
1084    typically obtained via a handwritten query/PreparedStatement. The resulting 
1085    ResultSet should contain all of the
1086    column names of table, prefixed with the specified <i>prefix</i> argument.
1087    a select statement that specified all fields or used a <tt>select <b>*</b>..</tt>
1088    clause.
1089    <p>
1090    In the select clause, we could also be selecting multiple tables. To disambiguate
1091    between the same field names that may exist in multiple tables, this method 
1092    also requires that the query should use a <font color=blue>prefix</font>
1093    (some arbitrary prefix) before column names, such as:
1094    <blockquote><pre>
1095    <font color=blue>foo</font>_column1
1096    <font color=blue>foo</font>_column2
1097    ...etc.
1098    </pre></blockquote>
1099    This prefix will typically be the same as the table abbreviation chosen via the <b>AS</b> clause. 
1100    If the AS clause is not used, then it is simpler to use the {@link getFromRS(ResultSet)} method instead
1101    <p><b>Note:</b> the "." will automatically be appended between the prefix and column name
1102    so the prefix should not end with a "." or "_", etc<p>
1103    <p>
1104    For example:
1105    <blockquote>
1106    <code>select <font color=blue>XXX</font>.a <b>AS</b> <font color=blue>XXX</font>_a, <font color=red>YYY</font>.a <b>AS</b> <font color=red>YYY</font>_a from <font color=blue>foo as XXX</font>, <font color=red>bar as YYY</font> where foo.a = bar.a;</code>
1107    </blockquote>
1108    The {@link #columns} method conveniently returns a list of column names in fully qualified format 
1109    and is useful for this purpose.
1110    <p>Note: This method will read the <i>current</i> row from the specified result set
1111    and will <b>not</b> move the result set pointer to the next row after the current
1112    row has been read. The result set should be appropriately positioned [via <tt>rs.next()</tt>]
1113    <i>before</i> calling this method.
1114    
1115    @return a new {@link 
1116    alltypes} object populated with the contents of the next    row from the result set or <tt> null </tt> if
1117        the ResultSet was empty.
1118    */
1119    public static alltypes getFromRS(final ResultSet rs, String prefix) throws SQLException
1120      {
1121      __getfromrs_called++;
1122      Argcheck.notnull(rs, "the specified resultset parameter was null");
1123      boolean hasrow = ! rs.isAfterLast();
1124      if (! hasrow) { 
1125        return null; 
1126        } 
1127      alltypes bean = new alltypes();
1128    
1129      bean.set_id( rs.getInt(prefix+"_id") );
1130      bean.__orig_id = rs.getInt(prefix+"_id"); /* save original PK */
1131      if (rs.wasNull()) {
1132        bean.__isNullInDB_id = true;
1133        }
1134      bean.set_smallint_val( rs.getShort(prefix+"_smallint_val") );
1135      if (rs.wasNull()) {
1136        bean.__isNullInDB_smallint_val = true;
1137        }
1138      bean.set_int_val( rs.getInt(prefix+"_int_val") );
1139      if (rs.wasNull()) {
1140        bean.__isNullInDB_int_val = true;
1141        }
1142      bean.set_bigint_val( rs.getLong(prefix+"_bigint_val") );
1143      if (rs.wasNull()) {
1144        bean.__isNullInDB_bigint_val = true;
1145        }
1146      bean.set_float_val( rs.getFloat(prefix+"_float_val") );
1147      if (rs.wasNull()) {
1148        bean.__isNullInDB_float_val = true;
1149        }
1150      bean.set_double_val( rs.getDouble(prefix+"_double_val") );
1151      if (rs.wasNull()) {
1152        bean.__isNullInDB_double_val = true;
1153        }
1154      bean.set_numeric_val( rs.getBigDecimal(prefix+"_numeric_val") );
1155      if (rs.wasNull()) {
1156        bean.__isNullInDB_numeric_val = true;
1157        }
1158      bean.set_char_val( rs.getString(prefix+"_char_val") );
1159      if (rs.wasNull()) {
1160        bean.__isNullInDB_char_val = true;
1161        }
1162      bean.set_varchar_val( rs.getString(prefix+"_varchar_val") );
1163      if (rs.wasNull()) {
1164        bean.__isNullInDB_varchar_val = true;
1165        }
1166      bean.set_longvarchar_val( rs.getString(prefix+"_longvarchar_val") );
1167      if (rs.wasNull()) {
1168        bean.__isNullInDB_longvarchar_val = true;
1169        }
1170      bean.set_date_val( rs.getDate(prefix+"_date_val") );
1171      if (rs.wasNull()) {
1172        bean.__isNullInDB_date_val = true;
1173        }
1174      bean.set_time_val( rs.getTime(prefix+"_time_val") );
1175      if (rs.wasNull()) {
1176        bean.__isNullInDB_time_val = true;
1177        }
1178      bean.set_timestamp_val( rs.getTimestamp(prefix+"_timestamp_val") );
1179      if (rs.wasNull()) {
1180        bean.__isNullInDB_timestamp_val = true;
1181        }
1182      bean.set_bit_val( ((Boolean) rs.getObject(prefix+"_bit_val")) );
1183      if (rs.wasNull()) {
1184        bean.__isNullInDB_bit_val = true;
1185        }
1186      bean.set_array_val( rs.getArray(prefix+"_array_val") );
1187      if (rs.wasNull()) {
1188        bean.__isNullInDB_array_val = true;
1189        }
1190      bean.set_boolean_val( ((Boolean) rs.getObject(prefix+"_boolean_val")) );
1191      if (rs.wasNull()) {
1192        bean.__isNullInDB_boolean_val = true;
1193        }
1194      bean.set_varbinary_val( rs.getBytes(prefix+"_varbinary_val") );
1195      if (rs.wasNull()) {
1196        bean.__isNullInDB_varbinary_val = true;
1197        }
1198      bean.set_json_val( rs.getString(prefix+"_json_val") );
1199      if (rs.wasNull()) {
1200        bean.__isNullInDB_json_val = true;
1201        }
1202      bean.set_jsonb_val( rs.getString(prefix+"_jsonb_val") );
1203      if (rs.wasNull()) {
1204        bean.__isNullInDB_jsonb_val = true;
1205        }
1206    
1207      /* set to true when instantiated new, false when we populate the bean from a resultset */
1208      bean.setNew(false);
1209      /* it's not modified, just loaded from the database */
1210      bean.resetModified();
1211      return bean;
1212      }
1213    
1214    /** 
1215    Creates and returns a new <tt>alltypes</tt> object that represents a row from the specified ResultSet. For this method
1216    to work properly, the specified ResultSet should contain <b>all</b> (typically via <b>select *
1217    </b>) of the column names of table.<tt>alltypes</tt>.
1218    <p>
1219    This method does not prepend the table name to columns when reading data from
1220    the result set. It is useful when writing a JDBC query by hand that uses a single table
1221    (no joins) and then converting the returned result set into objects of this
1222    class. For example:
1223    <p>
1224    <code>select a, b, c, c*2 from foo where a = 1;</code>
1225    <p>
1226    This method will expect columns to be called <code><i>a, b, c</i></code> (no column aliases) in the returned
1227    result set. In this example, there is only one table <code>foo</code> so qualifying the column
1228    names, like <code>foo.a as foo_a</code> is not necessary). Also note, for this method to work properly, the 
1229    column list<blockquote><code>select <i>a, b, c </i></code> ...</blockquote> should be complete, i.e., contain <i>at least</i> all the columns
1230    of this table (<i>additional</i> expressions like c*2 are fine). It is slightly less efficient to retrieve all columns
1231    especially for large tables but to construct a row into an object, we need all the fields. To be safe, use <blockquote><tt>select * ....</tt></blockquote>
1232    <p>
1233    Of course, if one needs a subset of columns, one can use the ResultSet directly and forego trying to
1234    convert a ResultSet row into an corresponding object
1235    <p> 
1236    See {@link getFromRS(ResultSet)} which is more useful when writing a JDBC
1237    query that uses multiple table joins.
1238    <p>Note: This method will read the <i>current</i> row from the specified result set
1239    and will <b>not</b> move the result set pointer to the next row after the current
1240    row has been read. The result set should be appropriately positioned [via <tt>rs.next()</tt>]
1241    <i>before</i> calling this method.
1242    
1243    @return a new {@link alltypes} object populated with the contents of the next
1244        row from the result set or <tt> null </tt> if
1245        the ResultSet was empty.
1246    */
1247    public static alltypes getFromRS1Table(final ResultSet rs) throws SQLException
1248      {
1249      __getfromrs_called++;
1250      Argcheck.notnull(rs, "the specified resultset parameter was null");
1251      boolean hasrow = ! rs.isAfterLast();
1252      if (! hasrow) { 
1253        return null; 
1254        } 
1255      alltypes bean = new alltypes();
1256    
1257      bean.set_id( rs.getInt(1) );
1258      bean.__orig_id = rs.getInt(1); /* save original PK */
1259      if (rs.wasNull()) {
1260        bean.__isNullInDB_id = true;
1261        }
1262      bean.set_smallint_val( rs.getShort(2) );
1263      if (rs.wasNull()) {
1264        bean.__isNullInDB_smallint_val = true;
1265        }
1266      bean.set_int_val( rs.getInt(3) );
1267      if (rs.wasNull()) {
1268        bean.__isNullInDB_int_val = true;
1269        }
1270      bean.set_bigint_val( rs.getLong(4) );
1271      if (rs.wasNull()) {
1272        bean.__isNullInDB_bigint_val = true;
1273        }
1274      bean.set_float_val( rs.getFloat(5) );
1275      if (rs.wasNull()) {
1276        bean.__isNullInDB_float_val = true;
1277        }
1278      bean.set_double_val( rs.getDouble(6) );
1279      if (rs.wasNull()) {
1280        bean.__isNullInDB_double_val = true;
1281        }
1282      bean.set_numeric_val( rs.getBigDecimal(7) );
1283      if (rs.wasNull()) {
1284        bean.__isNullInDB_numeric_val = true;
1285        }
1286      bean.set_char_val( rs.getString(8) );
1287      if (rs.wasNull()) {
1288        bean.__isNullInDB_char_val = true;
1289        }
1290      bean.set_varchar_val( rs.getString(9) );
1291      if (rs.wasNull()) {
1292        bean.__isNullInDB_varchar_val = true;
1293        }
1294      bean.set_longvarchar_val( rs.getString(10) );
1295      if (rs.wasNull()) {
1296        bean.__isNullInDB_longvarchar_val = true;
1297        }
1298      bean.set_date_val( rs.getDate(11) );
1299      if (rs.wasNull()) {
1300        bean.__isNullInDB_date_val = true;
1301        }
1302      bean.set_time_val( rs.getTime(12) );
1303      if (rs.wasNull()) {
1304        bean.__isNullInDB_time_val = true;
1305        }
1306      bean.set_timestamp_val( rs.getTimestamp(13) );
1307      if (rs.wasNull()) {
1308        bean.__isNullInDB_timestamp_val = true;
1309        }
1310      bean.set_bit_val( ((Boolean) rs.getObject(14)) );
1311      if (rs.wasNull()) {
1312        bean.__isNullInDB_bit_val = true;
1313        }
1314      bean.set_array_val( rs.getArray(15) );
1315      if (rs.wasNull()) {
1316        bean.__isNullInDB_array_val = true;
1317        }
1318      bean.set_boolean_val( ((Boolean) rs.getObject(16)) );
1319      if (rs.wasNull()) {
1320        bean.__isNullInDB_boolean_val = true;
1321        }
1322      bean.set_varbinary_val( rs.getBytes(17) );
1323      if (rs.wasNull()) {
1324        bean.__isNullInDB_varbinary_val = true;
1325        }
1326      bean.set_json_val( rs.getString(18) );
1327      if (rs.wasNull()) {
1328        bean.__isNullInDB_json_val = true;
1329        }
1330      bean.set_jsonb_val( rs.getString(19) );
1331      if (rs.wasNull()) {
1332        bean.__isNullInDB_jsonb_val = true;
1333        }
1334    
1335      /* set to true when instantiated but this should be false
1336       whenever we populate the bean from a result set */
1337      bean.setNew(false);
1338      //it's not modified, just loaded from the database
1339      bean.resetModified();
1340      return bean;
1341      }
1342    
1343    private static alltypes decodeFromRS(final ResultSet rs) throws SQLException
1344      {
1345      Argcheck.notnull(rs, "the specified resultset parameter was null");
1346      boolean hasrow = rs.next();
1347      if (! hasrow) { 
1348        return null; 
1349        } 
1350      alltypes bean = new alltypes();
1351    
1352      bean.set_id( rs.getInt(1) );
1353      bean.__orig_id = rs.getInt(1); /* save original PK */
1354      if (rs.wasNull()) {
1355        bean.__isNullInDB_id = true;
1356        }
1357    
1358      bean.set_smallint_val( rs.getShort(2) );
1359      if (rs.wasNull()) {
1360        bean.__isNullInDB_smallint_val = true;
1361        }
1362    
1363      bean.set_int_val( rs.getInt(3) );
1364      if (rs.wasNull()) {
1365        bean.__isNullInDB_int_val = true;
1366        }
1367    
1368      bean.set_bigint_val( rs.getLong(4) );
1369      if (rs.wasNull()) {
1370        bean.__isNullInDB_bigint_val = true;
1371        }
1372    
1373      bean.set_float_val( rs.getFloat(5) );
1374      if (rs.wasNull()) {
1375        bean.__isNullInDB_float_val = true;
1376        }
1377    
1378      bean.set_double_val( rs.getDouble(6) );
1379      if (rs.wasNull()) {
1380        bean.__isNullInDB_double_val = true;
1381        }
1382    
1383      bean.set_numeric_val( rs.getBigDecimal(7) );
1384      if (rs.wasNull()) {
1385        bean.__isNullInDB_numeric_val = true;
1386        }
1387    
1388      bean.set_char_val( rs.getString(8) );
1389      if (rs.wasNull()) {
1390        bean.__isNullInDB_char_val = true;
1391        }
1392    
1393      bean.set_varchar_val( rs.getString(9) );
1394      if (rs.wasNull()) {
1395        bean.__isNullInDB_varchar_val = true;
1396        }
1397    
1398      bean.set_longvarchar_val( rs.getString(10) );
1399      if (rs.wasNull()) {
1400        bean.__isNullInDB_longvarchar_val = true;
1401        }
1402    
1403      bean.set_date_val( rs.getDate(11) );
1404      if (rs.wasNull()) {
1405        bean.__isNullInDB_date_val = true;
1406        }
1407    
1408      bean.set_time_val( rs.getTime(12) );
1409      if (rs.wasNull()) {
1410        bean.__isNullInDB_time_val = true;
1411        }
1412    
1413      bean.set_timestamp_val( rs.getTimestamp(13) );
1414      if (rs.wasNull()) {
1415        bean.__isNullInDB_timestamp_val = true;
1416        }
1417    
1418      bean.set_bit_val( ((Boolean) rs.getObject(14)) );
1419      if (rs.wasNull()) {
1420        bean.__isNullInDB_bit_val = true;
1421        }
1422    
1423      bean.set_array_val( rs.getArray(15) );
1424      if (rs.wasNull()) {
1425        bean.__isNullInDB_array_val = true;
1426        }
1427    
1428      bean.set_boolean_val( ((Boolean) rs.getObject(16)) );
1429      if (rs.wasNull()) {
1430        bean.__isNullInDB_boolean_val = true;
1431        }
1432    
1433      bean.set_varbinary_val( rs.getBytes(17) );
1434      if (rs.wasNull()) {
1435        bean.__isNullInDB_varbinary_val = true;
1436        }
1437    
1438      bean.set_json_val( rs.getString(18) );
1439      if (rs.wasNull()) {
1440        bean.__isNullInDB_json_val = true;
1441        }
1442    
1443      bean.set_jsonb_val( rs.getString(19) );
1444      if (rs.wasNull()) {
1445        bean.__isNullInDB_jsonb_val = true;
1446        }
1447    
1448    
1449      /* set to true when newly instantiated but this should be false
1450       whenever we populate the bean from a result set */
1451      bean.setNew(false);
1452      //it's not modified, just loaded from the database
1453      bean.resetModified();
1454      return bean;
1455      }
1456    
1457    /**
1458    Saves the specified object into the database. If the specified
1459    object was newly created, then it is <span style="font-variant:
1460    small-caps">insert</span>'ed into the database, else (if it was retrieved
1461    earlier from the database) it is <span 
1462    style="font-variant: small-caps">update</span>'ed. (this can be
1463    overriden by the {@link #update update} method). If the object is
1464    inserted as a new row, then after insertion, the values of
1465    serial/auto-incremented columns will be automatically available via the
1466    appropriate getXXX() methods on that object.
1467    <p>
1468    <b>NOTE 1:</b> When saving an object, only modified fields are
1469    saved. Do not rely on default field values (such as null) of newly
1470    created objects; instead explicitly set the value (including to null
1471    if needed) of any field that should be saved to the database.
1472    <p>
1473    <b>NOTE 2:</b> Once an object is successfully saved, it is discarded
1474    and cannot be saved again and any attempt to save it again will
1475    result in a runtime exception. Objects that need to be modified
1476    again must be re-instantiated or re-populated from the database
1477    before they can be saved again. (the serial/auto-increment data will still be
1478    available, discarding only affects the ability to save the object
1479    again).
1480    <p>
1481    <b>Note 3:</b> <font color='red'>For various reasons/flexiblity, default database values
1482    for columns <i>other</i> than serial columns are <b>not</b> available
1483    in the saved object. To get these values, retrieve the saved object again. (this is what
1484    we would have to do internally anyway). This is relevant, for example, when a column has
1485    a default value of a now() timestamp, and we need to get that timestamp after the object
1486    has been saved</font>
1487    
1488    @return   the number of rows inserted or updated (typically useful 
1489          to see if an update succeeded)
1490    @throws ValidateException   on a validation error
1491    @throws SQLException    on some SQL/Database error
1492    @throws IOException     by the available() method if/when
1493                  setting a stream for longvar/text types
1494    */
1495    public static int save(final Connection con, final alltypes bean) throws ValidateException, SQLException, IOException
1496      {
1497      __save_called++;
1498      Argcheck.notnull(bean, "the specified bean parameter was null");
1499      checkDiscarded(bean);
1500      if (! bean.isModified()) { 
1501        log.warn("bean=", bean, " not modified, IGNORING SAVE\n====DEBUG STACK TRACE====\n", IOUtil.throwableToString(new Exception()));
1502        return 0;
1503        }
1504      PreparedStatement ps = null;
1505    
1506      boolean inserting_a_row = false;
1507      if (bean.isNew() && ! bean.__force_update) 
1508        {  //insert new row
1509        validateBeforeSaveNew(bean);
1510        int __count = 0;
1511        inserting_a_row = true;
1512        final StringBuilder buf = new StringBuilder(512);
1513        buf.append("INSERT into alltypes (");
1514        if (bean.isModified_smallint_val()) { 
1515          buf.append("smallint_val").append(", ");
1516          __count++;
1517          }
1518        if (bean.isModified_int_val()) { 
1519          buf.append("int_val").append(", ");
1520          __count++;
1521          }
1522        if (bean.isModified_bigint_val()) { 
1523          buf.append("bigint_val").append(", ");
1524          __count++;
1525          }
1526        if (bean.isModified_float_val()) { 
1527          buf.append("float_val").append(", ");
1528          __count++;
1529          }
1530        if (bean.isModified_double_val()) { 
1531          buf.append("double_val").append(", ");
1532          __count++;
1533          }
1534        if (bean.isModified_numeric_val()) { 
1535          buf.append("numeric_val").append(", ");
1536          __count++;
1537          }
1538        if (bean.isModified_char_val()) { 
1539          buf.append("char_val").append(", ");
1540          __count++;
1541          }
1542        if (bean.isModified_varchar_val()) { 
1543          buf.append("varchar_val").append(", ");
1544          __count++;
1545          }
1546        if (bean.isModified_longvarchar_val()) { 
1547          buf.append("longvarchar_val").append(", ");
1548          __count++;
1549          }
1550        if (bean.isModified_date_val()) { 
1551          buf.append("date_val").append(", ");
1552          __count++;
1553          }
1554        if (bean.isModified_time_val()) { 
1555          buf.append("time_val").append(", ");
1556          __count++;
1557          }
1558        if (bean.isModified_timestamp_val()) { 
1559          buf.append("timestamp_val").append(", ");
1560          __count++;
1561          }
1562        if (bean.isModified_bit_val()) { 
1563          buf.append("bit_val").append(", ");
1564          __count++;
1565          }
1566        if (bean.isModified_array_val()) { 
1567          buf.append("array_val").append(", ");
1568          __count++;
1569          }
1570        if (bean.isModified_boolean_val()) { 
1571          buf.append("boolean_val").append(", ");
1572          __count++;
1573          }
1574        if (bean.isModified_varbinary_val()) { 
1575          buf.append("varbinary_val").append(", ");
1576          __count++;
1577          }
1578        if (bean.isModified_json_val()) { 
1579          buf.append("json_val").append(", ");
1580          __count++;
1581          }
1582        if (bean.isModified_jsonb_val()) { 
1583          buf.append("jsonb_val").append(", ");
1584          __count++;
1585          }
1586    
1587        if (__count == 0) {
1588          throw new ValidateException("Cannot save this bean because no column has been modified. Use JDBC directly as needed.\n");
1589        }
1590        buf.setLength(buf.length() - 2);
1591        buf.append(") values (");
1592        for (int n = 0; n < __count; n++) { 
1593          buf.append("?");
1594          if ((n+1) < __count)
1595            buf.append(", ");
1596          }
1597        buf.append(")");
1598    
1599        final String insertByPKStmt = buf.toString();
1600        ps = prepareStatement(con, insertByPKStmt);
1601        /* Insert any changed values into our prepared statement */
1602        int pos = 0;
1603        if (bean.isModified_smallint_val()) {
1604          pos++;
1605          if (bean.isModifiedSetNull_smallint_val()) { /* nullable in db */
1606            ps.setNull(pos,5)/*SMALLINT*/;
1607            }
1608          else{
1609            short smallint_val = bean.get_smallint_val();
1610            ps.setShort(pos, smallint_val); 
1611            }
1612          }
1613        if (bean.isModified_int_val()) {
1614          pos++;
1615          int int_val = bean.get_int_val();
1616          ps.setInt(pos, int_val); 
1617          }
1618        if (bean.isModified_bigint_val()) {
1619          pos++;
1620          if (bean.isModifiedSetNull_bigint_val()) { /* nullable in db */
1621            ps.setNull(pos,-5)/*BIGINT*/;
1622            }
1623          else{
1624            long bigint_val = bean.get_bigint_val();
1625            ps.setLong(pos, bigint_val); 
1626            }
1627          }
1628        if (bean.isModified_float_val()) {
1629          pos++;
1630          if (bean.isModifiedSetNull_float_val()) { /* nullable in db */
1631            ps.setNull(pos,7)/*REAL*/;
1632            }
1633          else{
1634            float float_val = bean.get_float_val();
1635            ps.setFloat(pos, float_val); 
1636            }
1637          }
1638        if (bean.isModified_double_val()) {
1639          pos++;
1640          if (bean.isModifiedSetNull_double_val()) { /* nullable in db */
1641            ps.setNull(pos,8)/*DOUBLE*/;
1642            }
1643          else{
1644            double double_val = bean.get_double_val();
1645            ps.setDouble(pos, double_val); 
1646            }
1647          }
1648        if (bean.isModified_numeric_val()) {
1649          pos++;
1650          BigDecimal numeric_val = bean.get_numeric_val();
1651          ps.setBigDecimal(pos, numeric_val); 
1652          }
1653        if (bean.isModified_char_val()) {
1654          pos++;
1655          String char_val = bean.get_char_val();
1656          ps.setString(pos, char_val); 
1657          }
1658        if (bean.isModified_varchar_val()) {
1659          pos++;
1660          String varchar_val = bean.get_varchar_val();
1661          ps.setString(pos, varchar_val); 
1662          }
1663        if (bean.isModified_longvarchar_val()) {
1664          pos++;
1665          String longvarchar_val = bean.get_longvarchar_val();
1666          ps.setString(pos, longvarchar_val); 
1667          }
1668        if (bean.isModified_date_val()) {
1669          pos++;
1670          java.sql.Date date_val = bean.get_date_val();
1671          ps.setDate(pos, date_val); 
1672          }
1673        if (bean.isModified_time_val()) {
1674          pos++;
1675          Time time_val = bean.get_time_val();
1676          ps.setTime(pos, time_val); 
1677          }
1678        if (bean.isModified_timestamp_val()) {
1679          pos++;
1680          Timestamp timestamp_val = bean.get_timestamp_val();
1681          ps.setTimestamp(pos, timestamp_val); 
1682          }
1683        if (bean.isModified_bit_val()) {
1684          pos++;
1685          Boolean bit_val = bean.get_bit_val();
1686          ps.setObject(pos, bit_val); 
1687          }
1688        if (bean.isModified_array_val()) {
1689          pos++;
1690          java.sql.Array array_val = bean.get_array_val();
1691          ps.setArray(pos, array_val); 
1692          }
1693        if (bean.isModified_boolean_val()) {
1694          pos++;
1695          Boolean boolean_val = bean.get_boolean_val();
1696          ps.setObject(pos, boolean_val); 
1697          }
1698        if (bean.isModified_varbinary_val()) {
1699          pos++;
1700          byte[] varbinary_val = bean.get_varbinary_val();
1701          ps.setBytes(pos, varbinary_val); 
1702          }
1703        if (bean.isModified_json_val()) {
1704          pos++;
1705          String json_val = bean.get_json_val();
1706          ps.setObject(pos, json_val, java.sql.Types.OTHER); 
1707          }
1708        if (bean.isModified_jsonb_val()) {
1709          pos++;
1710          String jsonb_val = bean.get_jsonb_val();
1711          ps.setObject(pos, jsonb_val, java.sql.Types.OTHER); 
1712          }
1713        }
1714      else //update existing row 
1715        {
1716        validateBeforeSaveUpdate(bean);
1717        int __count = 0;
1718        final StringBuilder buf = new StringBuilder(512);
1719        buf.append("UPDATE ");
1720        buf.append("alltypes");
1721        buf.append(" SET ");
1722        if (bean.isModified_smallint_val()) { 
1723          buf.append("smallint_val=?, ");
1724          __count++;
1725          }
1726        if (bean.isModified_int_val()) { 
1727          buf.append("int_val=?, ");
1728          __count++;
1729          }
1730        if (bean.isModified_bigint_val()) { 
1731          buf.append("bigint_val=?, ");
1732          __count++;
1733          }
1734        if (bean.isModified_float_val()) { 
1735          buf.append("float_val=?, ");
1736          __count++;
1737          }
1738        if (bean.isModified_double_val()) { 
1739          buf.append("double_val=?, ");
1740          __count++;
1741          }
1742        if (bean.isModified_numeric_val()) { 
1743          buf.append("numeric_val=?, ");
1744          __count++;
1745          }
1746        if (bean.isModified_char_val()) { 
1747          buf.append("char_val=?, ");
1748          __count++;
1749          }
1750        if (bean.isModified_varchar_val()) { 
1751          buf.append("varchar_val=?, ");
1752          __count++;
1753          }
1754        if (bean.isModified_longvarchar_val()) { 
1755          buf.append("longvarchar_val=?, ");
1756          __count++;
1757          }
1758        if (bean.isModified_date_val()) { 
1759          buf.append("date_val=?, ");
1760          __count++;
1761          }
1762        if (bean.isModified_time_val()) { 
1763          buf.append("time_val=?, ");
1764          __count++;
1765          }
1766        if (bean.isModified_timestamp_val()) { 
1767          buf.append("timestamp_val=?, ");
1768          __count++;
1769          }
1770        if (bean.isModified_bit_val()) { 
1771          buf.append("bit_val=?, ");
1772          __count++;
1773          }
1774        if (bean.isModified_array_val()) { 
1775          buf.append("array_val=?, ");
1776          __count++;
1777          }
1778        if (bean.isModified_boolean_val()) { 
1779          buf.append("boolean_val=?, ");
1780          __count++;
1781          }
1782        if (bean.isModified_varbinary_val()) { 
1783          buf.append("varbinary_val=?, ");
1784          __count++;
1785          }
1786        if (bean.isModified_json_val()) { 
1787          buf.append("json_val=?, ");
1788          __count++;
1789          }
1790        if (bean.isModified_jsonb_val()) { 
1791          buf.append("jsonb_val=?, ");
1792          __count++;
1793          }
1794    
1795        if (__count == 0) {
1796          throw new ValidateException("Cannot save this bean because no column has been modified. Use JDBC directly as needed.\n");
1797        }
1798        buf.setLength(buf.length() - 2);
1799        buf.append(" WHERE ");
1800        buf.append("id=?");
1801        ps = con.prepareStatement(buf.toString());
1802    
1803        /* Insert any changed values into our prepared statement */
1804        int pos = 0;
1805        if (bean.isModified_smallint_val()) {
1806          pos++;
1807          if (bean.isModifiedSetNull_smallint_val()) { /* nullable in db */
1808            ps.setNull(pos,5)/*SMALLINT*/;
1809            }
1810          else{
1811            short smallint_val = bean.get_smallint_val();
1812            ps.setShort(pos, smallint_val); 
1813            }
1814          }
1815        if (bean.isModified_int_val()) {
1816          pos++;
1817          int int_val = bean.get_int_val();
1818          ps.setInt(pos, int_val); 
1819          }
1820        if (bean.isModified_bigint_val()) {
1821          pos++;
1822          if (bean.isModifiedSetNull_bigint_val()) { /* nullable in db */
1823            ps.setNull(pos,-5)/*BIGINT*/;
1824            }
1825          else{
1826            long bigint_val = bean.get_bigint_val();
1827            ps.setLong(pos, bigint_val); 
1828            }
1829          }
1830        if (bean.isModified_float_val()) {
1831          pos++;
1832          if (bean.isModifiedSetNull_float_val()) { /* nullable in db */
1833            ps.setNull(pos,7)/*REAL*/;
1834            }
1835          else{
1836            float float_val = bean.get_float_val();
1837            ps.setFloat(pos, float_val); 
1838            }
1839          }
1840        if (bean.isModified_double_val()) {
1841          pos++;
1842          if (bean.isModifiedSetNull_double_val()) { /* nullable in db */
1843            ps.setNull(pos,8)/*DOUBLE*/;
1844            }
1845          else{
1846            double double_val = bean.get_double_val();
1847            ps.setDouble(pos, double_val); 
1848            }
1849          }
1850        if (bean.isModified_numeric_val()) {
1851          pos++;
1852          BigDecimal numeric_val = bean.get_numeric_val();
1853          ps.setBigDecimal(pos, numeric_val); 
1854          }
1855        if (bean.isModified_char_val()) {
1856          pos++;
1857          String char_val = bean.get_char_val();
1858          ps.setString(pos, char_val); 
1859          }
1860        if (bean.isModified_varchar_val()) {
1861          pos++;
1862          String varchar_val = bean.get_varchar_val();
1863          ps.setString(pos, varchar_val); 
1864          }
1865        if (bean.isModified_longvarchar_val()) {
1866          pos++;
1867          String longvarchar_val = bean.get_longvarchar_val();
1868          ps.setString(pos, longvarchar_val); 
1869          }
1870        if (bean.isModified_date_val()) {
1871          pos++;
1872          java.sql.Date date_val = bean.get_date_val();
1873          ps.setDate(pos, date_val); 
1874          }
1875        if (bean.isModified_time_val()) {
1876          pos++;
1877          Time time_val = bean.get_time_val();
1878          ps.setTime(pos, time_val); 
1879          }
1880        if (bean.isModified_timestamp_val()) {
1881          pos++;
1882          Timestamp timestamp_val = bean.get_timestamp_val();
1883          ps.setTimestamp(pos, timestamp_val); 
1884          }
1885        if (bean.isModified_bit_val()) {
1886          pos++;
1887          Boolean bit_val = bean.get_bit_val();
1888          ps.setObject(pos, bit_val); 
1889          }
1890        if (bean.isModified_array_val()) {
1891          pos++;
1892          java.sql.Array array_val = bean.get_array_val();
1893          ps.setArray(pos, array_val); 
1894          }
1895        if (bean.isModified_boolean_val()) {
1896          pos++;
1897          Boolean boolean_val = bean.get_boolean_val();
1898          ps.setObject(pos, boolean_val); 
1899          }
1900        if (bean.isModified_varbinary_val()) {
1901          pos++;
1902          byte[] varbinary_val = bean.get_varbinary_val();
1903          ps.setBytes(pos, varbinary_val); 
1904          }
1905        if (bean.isModified_json_val()) {
1906          pos++;
1907          String json_val = bean.get_json_val();
1908          ps.setObject(pos, json_val, java.sql.Types.OTHER); 
1909          }
1910        if (bean.isModified_jsonb_val()) {
1911          pos++;
1912          String jsonb_val = bean.get_jsonb_val();
1913          ps.setObject(pos, jsonb_val, java.sql.Types.OTHER); 
1914          }
1915    
1916        /* Set primary keys for the WHERE part of our prepared statement */
1917        int id = (bean.__force_update) ? bean.get_id() : bean.__orig_id;
1918        ps.setInt(++pos, id); 
1919        } //~else update;
1920    
1921      log.bug("Query to run: ", ps);
1922      int result = ps.executeUpdate();
1923      if (inserting_a_row) { //get auto increment info
1924        /* Retrieve values from auto-increment columns */
1925        ResultSet rs = null; Statement stmt = null;
1926        String query = null;
1927        boolean found = false;
1928    
1929        if (bean.isModified_id()) { 
1930          //column: id
1931          //not getting auto increment value for this column
1932          //since not using auto increment, a value was specified manually
1933          }
1934        else{
1935          stmt = con.createStatement();
1936          query = "select currval('alltypes_id_seq')";
1937          rs = stmt.executeQuery(query);
1938          found = rs.next();
1939          if (! found) throw new SQLException("No last inserted id returned");
1940          bean.set_id( rs.getInt(1));
1941          if (rs.wasNull()) {
1942            bean.__isNullInDB_id = true;
1943            }
1944          rs.close();
1945          }
1946        }
1947    
1948      //discard after saving/updating for safety
1949      bean.discard();
1950      return result;
1951      }
1952    
1953    /**
1954    Uses the specified object to update existing data in the database.
1955    <p>
1956    Note, the {@link #save save} method automatically saves newly created objects
1957    as <i>inserts</i> in the database (and prior <i>retrieved</i> objects, when
1958    subsequently modified, are saved as <i>updates</i>).
1959    <p>
1960    However, sometimes it is useful to create a <i>new</i> object and then
1961    use its data to <i>update</i> an existing row in the database.
1962    This method need <b>only</b> be called to save a <u>newly</u>
1963    created object as an <u>update</u> into the database (overriding the
1964    default action of saving new objects as inserts in the database).
1965    <p>
1966    Note, also, a bean can only be updated if the corresponding table it has
1967    at least one primary key defined. To update tables with no primary keys,
1968    use JDBC directly.
1969    <p>
1970    This method takes primary key(s) of {@link alltypes} as additional arguments and sets those in the
1971    specified bean before updating the database (this way the row to update
1972    can be uniquely identified).
1973    
1974    @see #save
1975    
1976    @return   the number of rows that were updated (typically useful 
1977          to see if an update succeeded)
1978    @throws ValidateException   on a validation error
1979    @throws SQLException    on some SQL/Database error
1980    */
1981    public static int update(final Connection con, final alltypes bean, int id) throws ValidateException, SQLException, IOException
1982      {
1983      bean.set_id(id);
1984    
1985      if (bean.isNew()) { /* force update (and not insert) for new bean */
1986        bean.__force_update = true;
1987        }
1988      return save(con, bean);
1989      }
1990    
1991    static private final String deleteStmt = "DELETE  from alltypes WHERE id=?";
1992    /** 
1993    Deletes this object from the database. <p>
1994    <b>NOTE 1:</b> Only objects that were retrieved from the database can be deleted. Newly
1995    created objects cannot be deleted since they do not yet exist in the database.
1996    Use {@link #deleteByKey deleteByKey} or {@link #deleteWhere deleteWhere} instead
1997    for arbitrary deletions. <p><b>NOTE 2:</b> Once an object is successfully
1998    deleted, it is discarded and cannot be deleted again and any attempt to delete
1999    it again will result in a runtime Exception.
2000    */
2001    public static void delete(final Connection con, alltypes bean) throws SQLException
2002      {
2003      __delete_called++;
2004      if (bean.isNew()) {
2005        throw new DBOException("Cannot delete new objects using this method. Use deleteByKey() or deleteWhere() instead");
2006        }
2007      checkDiscarded(bean);
2008      final PreparedStatement ps = prepareStatement(con, deleteStmt);
2009      int id = bean.get_id();
2010      ps.setInt(1, id); 
2011      log.bug("Query to run: ", ps);
2012      final int result = ps.executeUpdate();
2013      if (result != 1) { 
2014        throw new DBOException("The number of deleted rows was: " + result + "; [Should have been 1 row exactly] ");
2015        }
2016      }
2017    
2018    static private final String deleteByPKStmt = "DELETE  from alltypes WHERE id=?";
2019    /** 
2020    Deletes the rows with the specified primary key(s) from the database. <p>This method uses a prepared statement and is safe from SQL injection attacks
2021    */
2022    public static void deleteByKey(final Connection con, int id) throws SQLException
2023      {
2024      __deletebykey_called++;
2025      PreparedStatement ps = prepareStatement(con, deleteByPKStmt);
2026      ps.setInt(1, id); 
2027      log.bug("Query to run: ", ps);
2028      final int result = ps.executeUpdate();
2029      if (result != 1) { 
2030        throw new DBOException("The number of deleted rows was: " + result + "; [Should have been 1 row exactly] ");
2031        }
2032      }
2033    
2034    /** 
2035    Returns the rows returned by querying the table with the contents of
2036    the specified instance of <tt>alltypes</tt> or <tt>null</tt> if no
2037    rows were found. As many fields in <tt>alltypes</tt> can be set as
2038    needed and the values of all set fields (including fields explicitly
2039    set to <tt>null</tt>) are then used to perform the query. <p>Note,
2040    however that this method does use any primary key(s). If the 
2041    primary keys are known then one should use the {@link
2042    #deleteByKey deleteByKey} method to delete the data instead.
2043    <p>Likewise, to delete a previously fetched row, use the {@link 
2044    #delete delete} method. This method is really meant to create an new
2045    object, set various fields in it, and then use that to delete matching
2046    row(s) from the database in a type safe way.
2047    <p>
2048    This method is often convenient/safer than the {@link #deleteWhere
2049    deleteWhere} method (because the <tt>deleteWhere</tt> method takes
2050    an arbitrary query string which has to be properly escaped by the user).
2051    
2052    <p>However, as a middle ground, this method also takes an <tt>clause</tt> parameter which
2053    is sent as is to the database. For example, a clause can be:
2054    <blockquote><pre>
2055    List beans = table_fooMgr.<font color=blue>deleteUsing(proto, <b>"xyx > 5"</b>)</font>;
2056    </pre> </blockquote>
2057    This clause is optional. Specify <tt>null</tt> to not use it at all.
2058    If the clause is specified, do <font size='+1'><b>NOT</b></font> include the word <tt>WHERE</tt>.
2059    
2060    <p>Essentially, this method is a more convenient way to use a
2061    PreparedStatement. Internally, a prepared statement is created and
2062    it's parameters are set to fields that are set in this object).
2063    Using PreparedStatements directly is also perfectly fine. For
2064    example, the following are equivalent. 
2065    <p> Using a PreparedStatement:
2066    <blockquote><pre>
2067    String foo = "delete from table_foo where x = ? and y = ?";
2068    PreparedStatement ps = con.prepareStatement(foo);
2069    ps.setString(1, "somevalue");
2070    ps.setString(2, "othervalue");
2071    int rows_deleted = ps.executeUpdate();
2072    </pre> </blockquote>  
2073    
2074    Using this method:
2075    <blockquote><pre>
2076    table_foo proto = new table_foo();
2077    proto.set_x("somevalue"); //compile time safety
2078    proto.set_y("othervalue");  //compile time safety
2079    int rows_deleted = table_fooMgr.<font color=blue>deleteUsing</font>(proto);
2080    </pre></blockquote>
2081    @return   the number of rows deleted
2082    */
2083    public static int deleteUsing(final Connection con, final alltypes bean, final String clause) throws ValidateException, SQLException
2084      {
2085      __deleteusing_called++;
2086    
2087      Argcheck.notnull(bean, "the bean parameter was null (and should not be null)");
2088      if (! bean.isModified()) { 
2089        throw new ValidateException("bean=" + bean + " not modified, ignoring query");
2090        }
2091    
2092      final StringBuilder buf = new StringBuilder(512);
2093      buf.append("DELETE  from alltypes WHERE ");
2094    
2095      int __count = 0;
2096      if (bean.isModified_smallint_val()) { 
2097        if (bean.isModifiedSetNull_smallint_val()) {
2098          buf.append("smallint_val is NULL and ");
2099          }
2100        else{
2101          buf.append("smallint_val=? and ");
2102          __count++;
2103          }
2104        }
2105      if (bean.isModified_int_val()) { 
2106        buf.append("int_val=? and ");
2107        __count++;
2108        }
2109      if (bean.isModified_bigint_val()) { 
2110        if (bean.isModifiedSetNull_bigint_val()) {
2111          buf.append("bigint_val is NULL and ");
2112          }
2113        else{
2114          buf.append("bigint_val=? and ");
2115          __count++;
2116          }
2117        }
2118      if (bean.isModified_float_val()) { 
2119        if (bean.isModifiedSetNull_float_val()) {
2120          buf.append("float_val is NULL and ");
2121          }
2122        else{
2123          buf.append("float_val=? and ");
2124          __count++;
2125          }
2126        }
2127      if (bean.isModified_double_val()) { 
2128        if (bean.isModifiedSetNull_double_val()) {
2129          buf.append("double_val is NULL and ");
2130          }
2131        else{
2132          buf.append("double_val=? and ");
2133          __count++;
2134          }
2135        }
2136      if (bean.isModified_numeric_val()) { 
2137        if (bean.get_numeric_val() == null) {
2138          buf.append("numeric_val is NULL and ");
2139          }
2140        else{
2141          buf.append("numeric_val=? and ");
2142          __count++;
2143          }
2144        }
2145      if (bean.isModified_char_val()) { 
2146        if (bean.get_char_val() == null) {
2147          buf.append("char_val is NULL and ");
2148          }
2149        else{
2150          buf.append("char_val=? and ");
2151          __count++;
2152          }
2153        }
2154      if (bean.isModified_varchar_val()) { 
2155        if (bean.get_varchar_val() == null) {
2156          buf.append("varchar_val is NULL and ");
2157          }
2158        else{
2159          buf.append("varchar_val=? and ");
2160          __count++;
2161          }
2162        }
2163      if (bean.isModified_longvarchar_val()) { 
2164        if (bean.get_longvarchar_val() == null) {
2165          buf.append("longvarchar_val is NULL and ");
2166          }
2167        else{
2168          buf.append("longvarchar_val=? and ");
2169          __count++;
2170          }
2171        }
2172      if (bean.isModified_date_val()) { 
2173        if (bean.get_date_val() == null) {
2174          buf.append("date_val is NULL and ");
2175          }
2176        else{
2177          buf.append("date_val=? and ");
2178          __count++;
2179          }
2180        }
2181      if (bean.isModified_time_val()) { 
2182        if (bean.get_time_val() == null) {
2183          buf.append("time_val is NULL and ");
2184          }
2185        else{
2186          buf.append("time_val=? and ");
2187          __count++;
2188          }
2189        }
2190      if (bean.isModified_timestamp_val()) { 
2191        if (bean.get_timestamp_val() == null) {
2192          buf.append("timestamp_val is NULL and ");
2193          }
2194        else{
2195          buf.append("timestamp_val=? and ");
2196          __count++;
2197          }
2198        }
2199      if (bean.isModified_bit_val()) { 
2200        if (bean.get_bit_val() == null) {
2201          buf.append("bit_val is NULL and ");
2202          }
2203        else{
2204          buf.append("bit_val=? and ");
2205          __count++;
2206          }
2207        }
2208      if (bean.isModified_array_val()) { 
2209        if (bean.get_array_val() == null) {
2210          buf.append("array_val is NULL and ");
2211          }
2212        else{
2213          buf.append("array_val=? and ");
2214          __count++;
2215          }
2216        }
2217      if (bean.isModified_boolean_val()) { 
2218        if (bean.get_boolean_val() == null) {
2219          buf.append("boolean_val is NULL and ");
2220          }
2221        else{
2222          buf.append("boolean_val=? and ");
2223          __count++;
2224          }
2225        }
2226      if (bean.isModified_varbinary_val()) { 
2227        if (bean.get_varbinary_val() == null) {
2228          buf.append("varbinary_val is NULL and ");
2229          }
2230        else{
2231          buf.append("varbinary_val=? and ");
2232          __count++;
2233          }
2234        }
2235      if (bean.isModified_json_val()) { 
2236        if (bean.get_json_val() == null) {
2237          buf.append("json_val is NULL and ");
2238          }
2239        else{
2240          buf.append("json_val=? and ");
2241          __count++;
2242          }
2243        }
2244      if (bean.isModified_jsonb_val()) { 
2245        if (bean.get_jsonb_val() == null) {
2246          buf.append("jsonb_val is NULL and ");
2247          }
2248        else{
2249          buf.append("jsonb_val=? and ");
2250          __count++;
2251          }
2252        }
2253      buf.setLength(buf.length() - 4);
2254      if (__count == 0) {
2255        throw new ValidateException("No non-PrimaryKey column was modified/set in this bean. You must set at least one such column. To delete by the Primary key, use the deleteByKey method instead.");
2256        }
2257      if (clause != null) {
2258        buf.append(" ");
2259        buf.append(clause);
2260        }
2261    
2262      final String getUsingPKStmt = buf.toString();
2263      PreparedStatement ps = prepareStatement(con, getUsingPKStmt);
2264      int pos = 0;
2265      if (bean.isModified_smallint_val()) {
2266        if (bean.isModifiedSetNull_smallint_val()) { 
2267          /* no value to set here, uses [xxx IS NULL] syntax*/
2268          }
2269        else{
2270          pos++;
2271          short smallint_val = bean.get_smallint_val();
2272          ps.setShort(pos, smallint_val); 
2273          }
2274        }
2275      if (bean.isModified_int_val()) {
2276          pos++;
2277          int int_val = bean.get_int_val();
2278          ps.setInt(pos, int_val); 
2279          }
2280      if (bean.isModified_bigint_val()) {
2281        if (bean.isModifiedSetNull_bigint_val()) { 
2282          /* no value to set here, uses [xxx IS NULL] syntax*/
2283          }
2284        else{
2285          pos++;
2286          long bigint_val = bean.get_bigint_val();
2287          ps.setLong(pos, bigint_val); 
2288          }
2289        }
2290      if (bean.isModified_float_val()) {
2291        if (bean.isModifiedSetNull_float_val()) { 
2292          /* no value to set here, uses [xxx IS NULL] syntax*/
2293          }
2294        else{
2295          pos++;
2296          float float_val = bean.get_float_val();
2297          ps.setFloat(pos, float_val); 
2298          }
2299        }
2300      if (bean.isModified_double_val()) {
2301        if (bean.isModifiedSetNull_double_val()) { 
2302          /* no value to set here, uses [xxx IS NULL] syntax*/
2303          }
2304        else{
2305          pos++;
2306          double double_val = bean.get_double_val();
2307          ps.setDouble(pos, double_val); 
2308          }
2309        }
2310      if (bean.isModified_numeric_val()) {
2311        if (bean.get_numeric_val() == null) { 
2312          /* no value to set here, uses [xxx IS NULL] syntax*/
2313          }
2314        else{
2315          pos++;
2316          BigDecimal numeric_val = bean.get_numeric_val();
2317          ps.setBigDecimal(pos, numeric_val); 
2318          }
2319        }
2320      if (bean.isModified_char_val()) {
2321        if (bean.get_char_val() == null) { 
2322          /* no value to set here, uses [xxx IS NULL] syntax*/
2323          }
2324        else{
2325          pos++;
2326          String char_val = bean.get_char_val();
2327          ps.setString(pos, char_val); 
2328          }
2329        }
2330      if (bean.isModified_varchar_val()) {
2331        if (bean.get_varchar_val() == null) { 
2332          /* no value to set here, uses [xxx IS NULL] syntax*/
2333          }
2334        else{
2335          pos++;
2336          String varchar_val = bean.get_varchar_val();
2337          ps.setString(pos, varchar_val); 
2338          }
2339        }
2340      if (bean.isModified_longvarchar_val()) {
2341        if (bean.get_longvarchar_val() == null) { 
2342          /* no value to set here, uses [xxx IS NULL] syntax*/
2343          }
2344        else{
2345          pos++;
2346          String longvarchar_val = bean.get_longvarchar_val();
2347          ps.setString(pos, longvarchar_val); 
2348          }
2349        }
2350      if (bean.isModified_date_val()) {
2351        if (bean.get_date_val() == null) { 
2352          /* no value to set here, uses [xxx IS NULL] syntax*/
2353          }
2354        else{
2355          pos++;
2356          java.sql.Date date_val = bean.get_date_val();
2357          ps.setDate(pos, date_val); 
2358          }
2359        }
2360      if (bean.isModified_time_val()) {
2361        if (bean.get_time_val() == null) { 
2362          /* no value to set here, uses [xxx IS NULL] syntax*/
2363          }
2364        else{
2365          pos++;
2366          Time time_val = bean.get_time_val();
2367          ps.setTime(pos, time_val); 
2368          }
2369        }
2370      if (bean.isModified_timestamp_val()) {
2371        if (bean.get_timestamp_val() == null) { 
2372          /* no value to set here, uses [xxx IS NULL] syntax*/
2373          }
2374        else{
2375          pos++;
2376          Timestamp timestamp_val = bean.get_timestamp_val();
2377          ps.setTimestamp(pos, timestamp_val); 
2378          }
2379        }
2380      if (bean.isModified_bit_val()) {
2381        if (bean.get_bit_val() == null) { 
2382          /* no value to set here, uses [xxx IS NULL] syntax*/
2383          }
2384        else{
2385          pos++;
2386          Boolean bit_val = bean.get_bit_val();
2387          ps.setObject(pos, bit_val); 
2388          }
2389        }
2390      if (bean.isModified_array_val()) {
2391        if (bean.get_array_val() == null) { 
2392          /* no value to set here, uses [xxx IS NULL] syntax*/
2393          }
2394        else{
2395          pos++;
2396          java.sql.Array array_val = bean.get_array_val();
2397          ps.setArray(pos, array_val); 
2398          }
2399        }
2400      if (bean.isModified_boolean_val()) {
2401        if (bean.get_boolean_val() == null) { 
2402          /* no value to set here, uses [xxx IS NULL] syntax*/
2403          }
2404        else{
2405          pos++;
2406          Boolean boolean_val = bean.get_boolean_val();
2407          ps.setObject(pos, boolean_val); 
2408          }
2409        }
2410      if (bean.isModified_varbinary_val()) {
2411        if (bean.get_varbinary_val() == null) { 
2412          /* no value to set here, uses [xxx IS NULL] syntax*/
2413          }
2414        else{
2415          pos++;
2416          byte[] varbinary_val = bean.get_varbinary_val();
2417          ps.setBytes(pos, varbinary_val); 
2418          }
2419        }
2420      if (bean.isModified_json_val()) {
2421        if (bean.get_json_val() == null) { 
2422          /* no value to set here, uses [xxx IS NULL] syntax*/
2423          }
2424        else{
2425          pos++;
2426          String json_val = bean.get_json_val();
2427          ps.setObject(pos, json_val, java.sql.Types.OTHER); 
2428          }
2429        }
2430      if (bean.isModified_jsonb_val()) {
2431        if (bean.get_jsonb_val() == null) { 
2432          /* no value to set here, uses [xxx IS NULL] syntax*/
2433          }
2434        else{
2435          pos++;
2436          String jsonb_val = bean.get_jsonb_val();
2437          ps.setObject(pos, jsonb_val, java.sql.Types.OTHER); 
2438          }
2439        }
2440      log.bug("Query to run: ", ps);
2441      List list = new ArrayList();
2442      int result = ps.executeUpdate();
2443      return result;
2444      }
2445    
2446    /** 
2447    Convenience method that invokes {@link getUsing(Connection, alltypes, String) getUsing} with an empty <i><tt>clause</tt></i> parameter.*/
2448    public static int deleteUsing(final Connection con, final alltypes bean) throws ValidateException, SQLException
2449      {
2450      return deleteUsing(con, bean, null);
2451      }
2452    
2453    /** 
2454    Deletes the rows with the specified where clause. <p><b>The
2455    where clause is sent as-is to the database and SQL injection
2456    attacks are possible if it is created as-is from a untrusted
2457    source.</b>
2458    (note: the string <tt>"WHERE"</tt> does <b>not</b> have to be
2459    specified in the clause. It is added automatically by this method).
2460    
2461    @return the number of rows deleted by the database
2462    */
2463    public static int deleteWhere(final Connection con, final String where) throws SQLException {
2464      __deletewhere_called++;
2465      Argcheck.notnull(where, "the where parameter was null (and should not be null)");
2466      final String stmt_string = "DELETE from alltypes WHERE " + where ;
2467      Statement stmt = con.createStatement();
2468      log.bug("Query to run: ", stmt_string);
2469      final int result = stmt.executeUpdate(stmt_string);
2470      return result;
2471    }
2472    
2473    private final static String countStmt = "SELECT count(*) from alltypes";
2474    /**
2475    Returns the count of all rows in the table. <p><b>Note</b>: This may
2476    be an expensive operation in MVCC databases like PostgresQL, Oracle and
2477    others, where an entire non-optimized table scan <i>may</i> be
2478    required -- hence speed will typically be O(n). However, on Postgres (for
2479    example), this is still very fast for small values of n (on a
2480    mid-level test machine) as of 2004, counting 4k records was about
2481    15 milli-seconds(ms); this scaled almost linearly, so count(*) for 16k records was
2482    about 70 ms, 65k records was about 370 ms, 524k records was about
2483    2000 ms and 1 million records was about 4000 ms. Results will vary
2484    on your machine and database but the general O(n) principle will
2485    remain the same.
2486    */
2487    public static int count(final Connection con) throws SQLException
2488      {
2489      __count_called++;
2490        int __count = -1;
2491      final Statement stmt = con.createStatement();
2492        final ResultSet rs = stmt.executeQuery(countStmt);
2493        if (rs.next())
2494          {
2495            __count = rs.getInt(1);
2496          }
2497      else { //rs returned no count, which should never happen
2498        throw new DBOException("The COUNT query [" + countStmt + "] returned no rows. [Should have returned 1 row exactly] ");
2499        }
2500      stmt.close();
2501      return __count;
2502      }
2503    
2504    /**
2505    Returns the count of rows in the table using the specified <tt>where</tt> clause.
2506    (note: the string <tt>"WHERE"</tt> does <b>not</b> have to be
2507    specified in the clause. It is added automatically by this method).
2508    
2509    @throws   IllegalArgumentException  if the where paramater was null
2510    */
2511    public static int countWhere(final Connection con, final String where) throws SQLException
2512      {
2513      __countwhere_called++;
2514      Argcheck.notnull(where, "the where parameter was null");
2515        int __count = -1;
2516      final String countWhereStmt = "SELECT count(*) from alltypes WHERE " + where;
2517      Statement stmt = con.createStatement();
2518      log.bug("Query to run: ", stmt, " ", countWhereStmt);
2519        ResultSet rs = stmt.executeQuery(countWhereStmt);
2520        if (rs.next())
2521          {
2522            __count = rs.getInt(1);
2523          }
2524      else { //rs returned no count, which should never happen
2525        throw new DBOException("The COUNT query [" + countWhereStmt + "] returned no rows. [Should have returned 1 row exactly] ");
2526        }
2527      stmt.close();
2528      return __count;
2529      }
2530    
2531    /** 
2532    Returns the rows count by querying the table with the contents of the
2533    specified instance of <tt>alltypes</tt> As many fields in <tt>alltypes</tt> can be set as needed and the
2534    values of all set fields (including fields explicitly set to
2535    <tt>null</tt>) are then used to perform the query. If the primary
2536    key(s) are known then one can also use the {@link #exists} method to
2537    see if that row exists in the database.
2538    <p>
2539    This method is often convenient/safer than the {@link #countWhere
2540    countWhere} method (because the <tt>countWhere</tt> method takes an
2541    arbitrary query string which has to be properly escaped by the
2542    user). 
2543    <p>Essentially, this method is a more convenient way to use a
2544    PreparedStatement (with parameters set to fields that are set in
2545    this object). Using PreparedStatements directly is also perfectly
2546    fine. For example, the following two are equivalent. <p>
2547    Using a PreparedStatement:
2548    <blockquote><pre>
2549    String foo = "select <i>count(*)</i> from table_foo where x = ? and y = ?";
2550    PreparedStatement ps = con.prepareStatement(foo);
2551    ps.setString(1, "somevalue");
2552    ps.setString(2, "othervalue");
2553    ResultSet rs  = ps.executeUpdate();
2554    rs.next();
2555    int count = rs.getInt(1);
2556    </pre> </blockquote>
2557    
2558    Using this method:
2559    <blockquote><pre>
2560    table_foo proto = new table_foo();
2561    proto.set_x("somevalue"); //compile time safety
2562    proto.set_y("othervalue");  //compile time safety
2563    int count = table_fooMgr.<font color=blue>countUsing</font>(proto);
2564    </pre> </blockquote>
2565    The clause is optional. Specify <tt>null</tt> to not use it at all.
2566    If the clause is specified, do <font size='+1'><b>NOT</b></font> include the word <tt>WHERE</tt>.
2567    */
2568    public static int countUsing(final Connection con, final alltypes bean, final String clause) throws ValidateException, SQLException
2569      {
2570      __countusing_called++;
2571      Argcheck.notnull(bean, "the bean parameter was null (and should not be null)"); if (! bean.isModified()) { 
2572        throw new ValidateException("bean=" + bean + " not modified, ignoring query");
2573        }
2574    
2575      int __count = 0;
2576      final StringBuilder buf = new StringBuilder(512);
2577      buf.append("SELECT count(*)  from alltypes WHERE ");
2578      if (bean.isModified_id()) { 
2579        buf.append("id=? and ");
2580        __count++;
2581        }
2582      if (bean.isModified_smallint_val()) { 
2583        if (bean.isModifiedSetNull_smallint_val()) {
2584          buf.append("smallint_val is NULL and ");
2585          }
2586        else{
2587          buf.append("smallint_val=? and ");
2588          __count++;
2589          }
2590        }
2591      if (bean.isModified_int_val()) { 
2592        buf.append("int_val=? and ");
2593        __count++;
2594        }
2595      if (bean.isModified_bigint_val()) { 
2596        if (bean.isModifiedSetNull_bigint_val()) {
2597          buf.append("bigint_val is NULL and ");
2598          }
2599        else{
2600          buf.append("bigint_val=? and ");
2601          __count++;
2602          }
2603        }
2604      if (bean.isModified_float_val()) { 
2605        if (bean.isModifiedSetNull_float_val()) {
2606          buf.append("float_val is NULL and ");
2607          }
2608        else{
2609          buf.append("float_val=? and ");
2610          __count++;
2611          }
2612        }
2613      if (bean.isModified_double_val()) { 
2614        if (bean.isModifiedSetNull_double_val()) {
2615          buf.append("double_val is NULL and ");
2616          }
2617        else{
2618          buf.append("double_val=? and ");
2619          __count++;
2620          }
2621        }
2622      if (bean.isModified_numeric_val()) { 
2623        if (bean.get_numeric_val() == null) {
2624          buf.append("numeric_val is NULL and ");
2625          }
2626        else{
2627          buf.append("numeric_val=? and ");
2628          __count++;
2629          }
2630        }
2631      if (bean.isModified_char_val()) { 
2632        if (bean.get_char_val() == null) {
2633          buf.append("char_val is NULL and ");
2634          }
2635        else{
2636          buf.append("char_val=? and ");
2637          __count++;
2638          }
2639        }
2640      if (bean.isModified_varchar_val()) { 
2641        if (bean.get_varchar_val() == null) {
2642          buf.append("varchar_val is NULL and ");
2643          }
2644        else{
2645          buf.append("varchar_val=? and ");
2646          __count++;
2647          }
2648        }
2649      if (bean.isModified_longvarchar_val()) { 
2650        if (bean.get_longvarchar_val() == null) {
2651          buf.append("longvarchar_val is NULL and ");
2652          }
2653        else{
2654          buf.append("longvarchar_val=? and ");
2655          __count++;
2656          }
2657        }
2658      if (bean.isModified_date_val()) { 
2659        if (bean.get_date_val() == null) {
2660          buf.append("date_val is NULL and ");
2661          }
2662        else{
2663          buf.append("date_val=? and ");
2664          __count++;
2665          }
2666        }
2667      if (bean.isModified_time_val()) { 
2668        if (bean.get_time_val() == null) {
2669          buf.append("time_val is NULL and ");
2670          }
2671        else{
2672          buf.append("time_val=? and ");
2673          __count++;
2674          }
2675        }
2676      if (bean.isModified_timestamp_val()) { 
2677        if (bean.get_timestamp_val() == null) {
2678          buf.append("timestamp_val is NULL and ");
2679          }
2680        else{
2681          buf.append("timestamp_val=? and ");
2682          __count++;
2683          }
2684        }
2685      if (bean.isModified_bit_val()) { 
2686        if (bean.get_bit_val() == null) {
2687          buf.append("bit_val is NULL and ");
2688          }
2689        else{
2690          buf.append("bit_val=? and ");
2691          __count++;
2692          }
2693        }
2694      if (bean.isModified_array_val()) { 
2695        if (bean.get_array_val() == null) {
2696          buf.append("array_val is NULL and ");
2697          }
2698        else{
2699          buf.append("array_val=? and ");
2700          __count++;
2701          }
2702        }
2703      if (bean.isModified_boolean_val()) { 
2704        if (bean.get_boolean_val() == null) {
2705          buf.append("boolean_val is NULL and ");
2706          }
2707        else{
2708          buf.append("boolean_val=? and ");
2709          __count++;
2710          }
2711        }
2712      if (bean.isModified_varbinary_val()) { 
2713        if (bean.get_varbinary_val() == null) {
2714          buf.append("varbinary_val is NULL and ");
2715          }
2716        else{
2717          buf.append("varbinary_val=? and ");
2718          __count++;
2719          }
2720        }
2721      if (bean.isModified_json_val()) { 
2722        if (bean.get_json_val() == null) {
2723          buf.append("json_val is NULL and ");
2724          }
2725        else{
2726          buf.append("json_val=? and ");
2727          __count++;
2728          }
2729        }
2730      if (bean.isModified_jsonb_val()) { 
2731        if (bean.get_jsonb_val() == null) {
2732          buf.append("jsonb_val is NULL and ");
2733          }
2734        else{
2735          buf.append("jsonb_val=? and ");
2736          __count++;
2737          }
2738        }
2739    
2740      buf.setLength(buf.length() - 4);
2741      if (clause != null) {
2742        buf.append(" ");
2743        buf.append(clause);
2744        }
2745    
2746      final String countUsingStmt = buf.toString();
2747      PreparedStatement ps = prepareStatement(con, countUsingStmt);
2748      int pos = 0;
2749      if (bean.isModified_id()) {
2750          pos++;
2751          int id = bean.get_id();
2752          ps.setInt(pos, id); 
2753          }
2754      if (bean.isModified_smallint_val()) {
2755        if (bean.isModifiedSetNull_smallint_val()) { 
2756          /* no value to set here, uses [xxx IS NULL] syntax*/
2757          }
2758        else{
2759          pos++;
2760          short smallint_val = bean.get_smallint_val();
2761          ps.setShort(pos, smallint_val); 
2762          }
2763        }
2764      if (bean.isModified_int_val()) {
2765          pos++;
2766          int int_val = bean.get_int_val();
2767          ps.setInt(pos, int_val); 
2768          }
2769      if (bean.isModified_bigint_val()) {
2770        if (bean.isModifiedSetNull_bigint_val()) { 
2771          /* no value to set here, uses [xxx IS NULL] syntax*/
2772          }
2773        else{
2774          pos++;
2775          long bigint_val = bean.get_bigint_val();
2776          ps.setLong(pos, bigint_val); 
2777          }
2778        }
2779      if (bean.isModified_float_val()) {
2780        if (bean.isModifiedSetNull_float_val()) { 
2781          /* no value to set here, uses [xxx IS NULL] syntax*/
2782          }
2783        else{
2784          pos++;
2785          float float_val = bean.get_float_val();
2786          ps.setFloat(pos, float_val); 
2787          }
2788        }
2789      if (bean.isModified_double_val()) {
2790        if (bean.isModifiedSetNull_double_val()) { 
2791          /* no value to set here, uses [xxx IS NULL] syntax*/
2792          }
2793        else{
2794          pos++;
2795          double double_val = bean.get_double_val();
2796          ps.setDouble(pos, double_val); 
2797          }
2798        }
2799      if (bean.isModified_numeric_val()) {
2800        if (bean.get_numeric_val() == null) { 
2801          /* no value to set here, uses [xxx IS NULL] syntax*/
2802          }
2803        else{
2804          pos++;
2805          BigDecimal numeric_val = bean.get_numeric_val();
2806          ps.setBigDecimal(pos, numeric_val); 
2807          }
2808        }
2809      if (bean.isModified_char_val()) {
2810        if (bean.get_char_val() == null) { 
2811          /* no value to set here, uses [xxx IS NULL] syntax*/
2812          }
2813        else{
2814          pos++;
2815          String char_val = bean.get_char_val();
2816          ps.setString(pos, char_val); 
2817          }
2818        }
2819      if (bean.isModified_varchar_val()) {
2820        if (bean.get_varchar_val() == null) { 
2821          /* no value to set here, uses [xxx IS NULL] syntax*/
2822          }
2823        else{
2824          pos++;
2825          String varchar_val = bean.get_varchar_val();
2826          ps.setString(pos, varchar_val); 
2827          }
2828        }
2829      if (bean.isModified_longvarchar_val()) {
2830        if (bean.get_longvarchar_val() == null) { 
2831          /* no value to set here, uses [xxx IS NULL] syntax*/
2832          }
2833        else{
2834          pos++;
2835          String longvarchar_val = bean.get_longvarchar_val();
2836          ps.setString(pos, longvarchar_val); 
2837          }
2838        }
2839      if (bean.isModified_date_val()) {
2840        if (bean.get_date_val() == null) { 
2841          /* no value to set here, uses [xxx IS NULL] syntax*/
2842          }
2843        else{
2844          pos++;
2845          java.sql.Date date_val = bean.get_date_val();
2846          ps.setDate(pos, date_val); 
2847          }
2848        }
2849      if (bean.isModified_time_val()) {
2850        if (bean.get_time_val() == null) { 
2851          /* no value to set here, uses [xxx IS NULL] syntax*/
2852          }
2853        else{
2854          pos++;
2855          Time time_val = bean.get_time_val();
2856          ps.setTime(pos, time_val); 
2857          }
2858        }
2859      if (bean.isModified_timestamp_val()) {
2860        if (bean.get_timestamp_val() == null) { 
2861          /* no value to set here, uses [xxx IS NULL] syntax*/
2862          }
2863        else{
2864          pos++;
2865          Timestamp timestamp_val = bean.get_timestamp_val();
2866          ps.setTimestamp(pos, timestamp_val); 
2867          }
2868        }
2869      if (bean.isModified_bit_val()) {
2870        if (bean.get_bit_val() == null) { 
2871          /* no value to set here, uses [xxx IS NULL] syntax*/
2872          }
2873        else{
2874          pos++;
2875          Boolean bit_val = bean.get_bit_val();
2876          ps.setObject(pos, bit_val); 
2877          }
2878        }
2879      if (bean.isModified_array_val()) {
2880        if (bean.get_array_val() == null) { 
2881          /* no value to set here, uses [xxx IS NULL] syntax*/
2882          }
2883        else{
2884          pos++;
2885          java.sql.Array array_val = bean.get_array_val();
2886          ps.setArray(pos, array_val); 
2887          }
2888        }
2889      if (bean.isModified_boolean_val()) {
2890        if (bean.get_boolean_val() == null) { 
2891          /* no value to set here, uses [xxx IS NULL] syntax*/
2892          }
2893        else{
2894          pos++;
2895          Boolean boolean_val = bean.get_boolean_val();
2896          ps.setObject(pos, boolean_val); 
2897          }
2898        }
2899      if (bean.isModified_varbinary_val()) {
2900        if (bean.get_varbinary_val() == null) { 
2901          /* no value to set here, uses [xxx IS NULL] syntax*/
2902          }
2903        else{
2904          pos++;
2905          byte[] varbinary_val = bean.get_varbinary_val();
2906          ps.setBytes(pos, varbinary_val); 
2907          }
2908        }
2909      if (bean.isModified_json_val()) {
2910        if (bean.get_json_val() == null) { 
2911          /* no value to set here, uses [xxx IS NULL] syntax*/
2912          }
2913        else{
2914          pos++;
2915          String json_val = bean.get_json_val();
2916          ps.setObject(pos, json_val, java.sql.Types.OTHER); 
2917          }
2918        }
2919      if (bean.isModified_jsonb_val()) {
2920        if (bean.get_jsonb_val() == null) { 
2921          /* no value to set here, uses [xxx IS NULL] syntax*/
2922          }
2923        else{
2924          pos++;
2925          String jsonb_val = bean.get_jsonb_val();
2926          ps.setObject(pos, jsonb_val, java.sql.Types.OTHER); 
2927          }
2928        }
2929      log.bug("Query to run: ", ps);
2930      ResultSet rs = ps.executeQuery();
2931      if (! rs.next()) {
2932        throw new DBOException("The COUNT query [" + countUsingStmt + "] returned no rows. [Should have returned 1 row exactly] ");
2933        }
2934      int rows = rs.getInt(1);
2935      rs.close();
2936      return rows;
2937      }
2938    
2939    /** 
2940    Convenience method that invokes {@link getUsing(Connection, alltypes, String) getUsing} with an empty <i><tt>clause</tt></i> parameter.*/
2941    public static int countUsing(final Connection con, final alltypes bean) throws ValidateException, SQLException
2942      {
2943      return countUsing(con, bean, null);
2944      }
2945    
2946    static private final String existsStmt = "SELECT count(*) from alltypes WHERE id=?";
2947    /**
2948    Returns <tt>true</tt> if a row with the specified primary keys exists, <tt>false</tt> otherwise.
2949    <p>This method uses a prepared statement and is safe from SQL injection attacks
2950    */
2951    public static boolean exists(final Connection con, int id) throws SQLException
2952      {
2953      __exists_called++;
2954      PreparedStatement ps = prepareStatement(con, existsStmt);
2955      ps.setInt(1, id); 
2956      log.bug("Query to run: ", ps);
2957      ResultSet rs = ps.executeQuery();
2958      int __count = -1;
2959        if (rs.next())
2960          {
2961            __count = rs.getInt(1);
2962          }
2963      else { //rs returned no count, which should never happen
2964        throw new DBOException("The COUNT query [" + existsStmt + "] returned no rows. [Should have returned 1 row exactly] ");
2965        }
2966      rs.close();
2967      return (__count > 0); //exists if __count > 0
2968      }
2969    /**
2970    A thin wrapper around {@link getUsing(Connection,alltypes) getUsing}
2971    that returns <tt>false</tt> if no rows are returned, <tt>true</tt> otherwise.
2972    */
2973    public static boolean existsUsing(final Connection con, final alltypes bean) throws ValidateException, SQLException
2974      {
2975      final List list = getUsing(con, bean, null);
2976      return (list.size() > 0);
2977      }
2978    
2979    /**
2980    Returns a prepared statement given it's variable name.
2981    
2982    Essentially speeds up the creation of prepared statements perhaps
2983    using a per connection cache -- which makes sense for pooled
2984    connections since they are not closed but returned to the pool
2985    and hence don't need to "prepare" statements every time (the
2986    prepareStatement call is seperate from actually filling in the
2987    placeholders in a already created prepared statement -- which
2988    does need to be done every time). <p>
2989    Prepared statements are unique per connection, so multiple threads
2990    using different connections won't stomp over each other's prepared
2991    statements. Multiple threads using the SAME connection will cause
2992    bizarre errors but multiple threads won't get the same connection
2993    from the connection manager -- ever :-), so that should never happen.
2994    */
2995    private static final PreparedStatement prepareStatement ( final Connection con, final String sql) throws SQLException
2996      {
2997      if (! (con instanceof fc.jdbc.PooledConnection) ) { 
2998        return con.prepareStatement(sql);
2999        }
3000      final PooledConnection pc = (PooledConnection) con;
3001      return pc.getCachedPreparedStatement(sql);
3002      }
3003    
3004    private static final void checkDiscarded(final DBO bean) throws DBOException
3005      {
3006      if (bean.isDiscarded()) {
3007        throw new DBOException("===== Attempt to save a discarded object === " + bean);
3008        }
3009      }
3010    
3011    private static final java.util.Date __loadDate = new java.util.Date();
3012    /** Returns usage statistics for this class */
3013    public static String stats() 
3014      {
3015      //locally created _numberFormat for thread safety
3016      final java.text.NumberFormat _numberFormat = java.text.NumberFormat.getInstance();
3017      final String nl = fc.io.IOUtil.LINE_SEP;
3018      StringBuffer buf = new StringBuffer(256);
3019      buf.append("Class Name: [alltypesMgr]; Class loaded on: ");
3020      buf.append(__loadDate);
3021      buf.append(nl);
3022      buf.append("---- Start Usage Statistics ----").append(nl);
3023    
3024      ByteArrayOutputStream out = new ByteArrayOutputStream(512);
3025      TablePrinter.PrintConfig config = new TablePrinter.PrintConfig();
3026      config.setPrintBorders(false);
3027      config.setCellSpacing(1);
3028      config.setCellPadding(0);
3029      config.setAutoFit(true);
3030      TablePrinter p = new TablePrinter(2, new PrintStream(out), config);
3031      p.startTable();
3032    
3033      p.startRow();
3034      p.printCell("Method");
3035      p.printCell("# times called");
3036      p.endRow();
3037    
3038      p.startRow();
3039      p.printCell("getAll()");
3040      p.printCell(_numberFormat.format(__getall_called));
3041      p.endRow();
3042    
3043      p.startRow();
3044      p.printCell("getLimited()");
3045      p.printCell(_numberFormat.format(__getlimited_called));
3046      p.endRow();
3047    
3048      p.startRow();
3049      p.printCell("getByKey()");
3050      p.printCell(_numberFormat.format(__getbykey_called));
3051      p.endRow();
3052    
3053      p.startRow();
3054      p.printCell("getWhere()");
3055      p.printCell(_numberFormat.format(__getwhere_called));
3056      p.endRow();
3057    
3058      p.startRow();
3059      p.printCell("getUsing()");
3060      p.printCell(_numberFormat.format(__getusing_called));
3061      p.endRow();
3062    
3063      p.startRow();
3064      p.printCell("getUsing(prepared_stmt)");
3065      p.printCell(_numberFormat.format(__getusing_ps_called));
3066      p.endRow();
3067    
3068      p.startRow();
3069      p.printCell("getFromRS()");
3070      p.printCell(_numberFormat.format(__getfromrs_called));
3071      p.endRow();
3072    
3073      p.startRow();
3074      p.printCell("save()");
3075      p.printCell(_numberFormat.format(__save_called));
3076      p.endRow();
3077    
3078      p.startRow();
3079      p.printCell("delete()");
3080      p.printCell(_numberFormat.format(__delete_called));
3081      p.endRow();
3082    
3083      p.startRow();
3084      p.printCell("deleteByKey()");
3085      p.printCell(_numberFormat.format(__deletebykey_called));
3086      p.endRow();
3087    
3088      p.startRow();
3089      p.printCell("deleteWhere()");
3090      p.printCell(_numberFormat.format(__deletewhere_called));
3091      p.endRow();
3092    
3093      p.startRow();
3094      p.printCell("deleteUsing()");
3095      p.printCell(_numberFormat.format(__deleteusing_called));
3096      p.endRow();
3097    
3098      p.startRow();
3099      p.printCell("count()");
3100      p.printCell(_numberFormat.format(__count_called));
3101      p.endRow();
3102    
3103      p.startRow();
3104      p.printCell("countWhere()");
3105      p.printCell(_numberFormat.format(__countwhere_called));
3106      p.endRow();
3107    
3108      p.startRow();
3109      p.printCell("countUsing()");
3110      p.printCell(_numberFormat.format(__countusing_called));
3111      p.endRow();
3112    
3113      p.startRow();
3114      p.printCell("exists()");
3115      p.printCell(_numberFormat.format(__exists_called));
3116      p.endRow();
3117    
3118      p.endTable();
3119      buf.append(out.toString());
3120      return buf.toString();
3121      }
3122    
3123    public String toString() 
3124      {
3125      return getClass().getName() + " [call stats() for more info]";
3126      }
3127    
3128    // ================ Validation  ==================== 
3129    
3130    /** 
3131    Creates and attaches validators for all the fields in the
3132    specified {@link fc.web.forms.Form}. These fields should
3133    <i>have the same name</i> in the form as in {@link alltypes}. If this is not the case, then the then the differences can be specifed
3134    as follows. <p>
3135    <dl>
3136    <dt>with a prefix</dt>
3137      <dd><tt>(prefix + alltypes column)</tt> should equal <tt>form fieldname</tt></dd>
3138    <dt>with a suffix</dt> 
3139      <dd><tt>(alltypes column + suffix)</tt> should equal <tt>form fieldname</tt></dd>
3140    <dt>with both a prefix/suffix</dt> 
3141      <dd><tt>(prefix + alltypes + suffix)</tt> should equal <tt>form fieldname</tt></dd>
3142    <dt>with a arbitrary map</dt> 
3143      <dd>[key] <tt>alltypes column</tt> -> [value] <tt>form fieldname</tt>
3144      <u>If a map is specified, then the prefix/suffix are not used.</u>
3145      </dd>
3146    </dl>
3147    <p>These validators are for database constraints such as <i>nullability</i> & <i>column length</i>.
3148    These validators save a lot of grunt-work in adding such schema
3149    constraints to the front-end {@link fc.web.forms.Form}. <p><b>However, <i>business and
3150    other validation constraints</i> still need to be manually added to
3151    the application code/front-end forms as/when needed</b>.
3152    <p>
3153    
3154    The following table shows the kind of validators added by this method
3155    <table border=1 width=90%>
3156    <tr bgcolor='#CCCCCC'>
3157      <td>Database SQL Type</td>
3158      <td><b>Nullable</b>validator</td>
3159      <td><b>Length</b> validator</td>
3160      <td><b>Digits only</b> input validator ({@link VText#allowIntegersOnly})</td>
3161    </tr>
3162      <tr>
3163        <td><tt>CHAR</tt>, <tt>VARCHAR</tt></td>
3164        <td>Yes (maximum length constraint).<br><font size='-1' color=red>This
3165        only applies to form fields that are subclasses of {@link 
3166        fc.web.forms.MaxSizable} </font></td>
3167        <td>-NO-</td>
3168      </tr>
3169      <tr>
3170        <td><tt>TINYINT, MEDIUMINT, INT, BIGINT (integral types)</tt></td>
3171        <td>Yes</td>
3172        <td>-NO-</td>
3173        <td>Yes to integer columns displayed using form fields that are subclasses of {@link fc.web.forms.AbstractText}<br> Note: <b>not</b> added non-<i>integral</i> number types such as <tt>FLOAT, REAL, DOUBLE, NUMERIC/DECIMAL</tt></td>
3174      </tr>
3175      <tr>
3176        <td>All other SQL types</td>
3177        <td>Yes</td>
3178        <td>-NO-</td>
3179      </tr>
3180    </table>
3181    <p>Automatic validators are very useful but can be very tricky to understand. It is
3182    suggested to invoke this method, print the form using it's <tt>toString</tt>
3183    method and then examine the output to see what validators were added If those
3184    automatic validators are too little, too many or too hard to understand, <u>then
3185    simply enoough, do NOT invoke this method and simply add validators by
3186    hand</u>. In particular, do <i>not</i> add automatic validators for
3187    <b>tables</b> in which a row is optional but <i>if</i> some column is filled in
3188    the front end form, <i>then</i> all columns must be filled.
3189    
3190    @param  form  the form containing fields (some or all) representing
3191            this and possible other tables. These field
3192            objects must have been added to the form prior
3193            to calling this method
3194    @param  prefix  an optional (null allowed) prefix to this table's column name with which the
3195            corresponding column was added to the form.
3196            A <tt>*</tt> specifies all possible prefixes
3197    @param  suffix  an optional suffix (null allowed) to this table's column name with which the 
3198            corresponding column was added to the form.
3199            A <tt>*</tt> specifies all possible suffixes
3200    @param  map   an optional map (null allowed) that maps this table's column name with which the 
3201            corresponding column was added to the form. 
3202            [key] <tt>table's column_name</tt> -> [value] <tt>form's fieldname</tt>
3203    */
3204    public static void addValidators(final fc.web.forms.Form form, final String prefix, final String suffix, final Map map) 
3205      {
3206      addValidators(form, prefix, suffix, map, false);
3207      }
3208    
3209    private static void addValidators(fc.web.forms.Form form, String prefix, String suffix, final Map map, final boolean onlyOnFilled) 
3210      {
3211      List list = null;
3212      Argcheck.notnull(form, "How can I add validators to the form when the form parameter was null ?");
3213      Field field = null;
3214      FieldValidator fv = null;
3215      String colname_in_form = null;
3216      //fields can be null if they are not being used in the html form
3217    
3218      /** serial (INTEGER); PK=yes; Nullable=false; AutoInc=true; MaxSize=10 */
3219      list = getFieldFromForm(form, "id", prefix, suffix, map, false);
3220      if (list.size() > 0) 
3221        { //add applicable automatic validators, empty if n/a
3222        for (int n = 0; n < list.size(); n++)
3223          {
3224          field = (Field) list.get(n);
3225          /* field is non-nullable but has a default value [nextval('alltypes_id_seq'::regclass)], skipping non-nullability validation */
3226    
3227          /* database type for this field is integral */
3228          if (field instanceof AbstractText) {
3229            fv = new VText((AbstractText)field, "Error: Please enter only numbers in this field")
3230              .allowIntegersOnly();
3231            }
3232          }
3233        }
3234    
3235      /** int2 (SMALLINT); Nullable=true; AutoInc=false; MaxSize=5 */
3236      list = getFieldFromForm(form, "smallint_val", prefix, suffix, map, true);
3237      if (list.size() > 0) 
3238        { //add applicable automatic validators, empty if n/a
3239        for (int n = 0; n < list.size(); n++)
3240          {
3241          field = (Field) list.get(n);
3242          /* field is nullable, skipping non-nullability validation */
3243    
3244          /* database type for this field is integral */
3245          if (field instanceof AbstractText) {
3246            fv = new VText((AbstractText)field, "Error: Please enter only numbers in this field")
3247              .allowIntegersOnly();
3248            }
3249          }
3250        }
3251    
3252      /** int4 (INTEGER); Nullable=false; AutoInc=false; MaxSize=10 */
3253      list = getFieldFromForm(form, "int_val", prefix, suffix, map, true);
3254      if (list.size() > 0) 
3255        { //add applicable automatic validators, empty if n/a
3256        for (int n = 0; n < list.size(); n++)
3257          {
3258          field = (Field) list.get(n);
3259          if (field instanceof Choice) {
3260            //choice fields are ignored because they can
3261            //mean false even when NOT selected/filled
3262            continue;
3263            }
3264          /* field is non-nullable */
3265          fv = new VFilled(field, "Error: Required field, please enter a value");
3266    
3267          /* database type for this field is integral */
3268          if (field instanceof AbstractText) {
3269            fv = new VText((AbstractText)field, "Error: Please enter only numbers in this field")
3270              .allowIntegersOnly();
3271            }
3272          }
3273        }
3274    
3275      /** int8 (BIGINT); Nullable=true; AutoInc=false; MaxSize=19 */
3276      list = getFieldFromForm(form, "bigint_val", prefix, suffix, map, true);
3277      if (list.size() > 0) 
3278        { //add applicable automatic validators, empty if n/a
3279        for (int n = 0; n < list.size(); n++)
3280          {
3281          field = (Field) list.get(n);
3282          /* field is nullable, skipping non-nullability validation */
3283    
3284          /* database type for this field is integral */
3285          if (field instanceof AbstractText) {
3286            fv = new VText((AbstractText)field, "Error: Please enter only numbers in this field")
3287              .allowIntegersOnly();
3288            }
3289          }
3290        }
3291    
3292      /** float4 (REAL); Nullable=true; AutoInc=false; MaxSize=8 */
3293      list = getFieldFromForm(form, "float_val", prefix, suffix, map, true);
3294      if (list.size() > 0) 
3295        { //add applicable automatic validators, empty if n/a
3296        for (int n = 0; n < list.size(); n++)
3297          {
3298          field = (Field) list.get(n);
3299          /* field is nullable, skipping non-nullability validation */
3300          }
3301        }
3302    
3303      /** float8 (DOUBLE); Nullable=true; AutoInc=false; MaxSize=17 */
3304      list = getFieldFromForm(form, "double_val", prefix, suffix, map, true);
3305      if (list.size() > 0) 
3306        { //add applicable automatic validators, empty if n/a
3307        for (int n = 0; n < list.size(); n++)
3308          {
3309          field = (Field) list.get(n);
3310          /* field is nullable, skipping non-nullability validation */
3311          }
3312        }
3313    
3314      /** numeric (NUMERIC); Nullable=true; AutoInc=false; MaxSize=5 */
3315      list = getFieldFromForm(form, "numeric_val", prefix, suffix, map, true);
3316      if (list.size() > 0) 
3317        { //add applicable automatic validators, empty if n/a
3318        for (int n = 0; n < list.size(); n++)
3319          {
3320          field = (Field) list.get(n);
3321          /* field is nullable, skipping non-nullability validation */
3322          }
3323        }
3324    
3325      /** bpchar (CHAR); Nullable=true; AutoInc=false; MaxSize=10 */
3326      list = getFieldFromForm(form, "char_val", prefix, suffix, map, true);
3327      if (list.size() > 0) 
3328        { //add applicable automatic validators, empty if n/a
3329        for (int n = 0; n < list.size(); n++)
3330          {
3331          field = (Field) list.get(n);
3332          /* field is nullable, skipping non-nullability validation */
3333          if (! (field instanceof MaxSizable)) {
3334            log.warn("Skipping maximum length validator for field '" + field.getName() + "'; [database type='CHAR', field.type='" +  field.getType() + "' is not MaxSizable]"); 
3335            }
3336          else{
3337            VText vt = new VText((MaxSizable) field, "Not enough or too many characters");
3338            vt.setMaxSize(10);
3339            }
3340          }
3341        }
3342    
3343      /** varchar (VARCHAR); Nullable=true; AutoInc=false; MaxSize=10 */
3344      list = getFieldFromForm(form, "varchar_val", prefix, suffix, map, true);
3345      if (list.size() > 0) 
3346        { //add applicable automatic validators, empty if n/a
3347        for (int n = 0; n < list.size(); n++)
3348          {
3349          field = (Field) list.get(n);
3350          /* field is nullable, skipping non-nullability validation */
3351          if (! (field instanceof MaxSizable)) {
3352            log.warn("Skipping maximum length validator for field '" + field.getName() + "'; [database type='VARCHAR', field.type='" +  field.getType() + "' is not MaxSizable]"); 
3353            }
3354          else{
3355            VText vt = new VText((MaxSizable) field, "Not enough or too many characters");
3356            vt.setMaxSize(10);
3357            }
3358          }
3359        }
3360    
3361      /** text (VARCHAR); Nullable=true; AutoInc=false; MaxSize=2147483647 */
3362      list = getFieldFromForm(form, "longvarchar_val", prefix, suffix, map, true);
3363      if (list.size() > 0) 
3364        { //add applicable automatic validators, empty if n/a
3365        for (int n = 0; n < list.size(); n++)
3366          {
3367          field = (Field) list.get(n);
3368          /* field is nullable, skipping non-nullability validation */
3369          if (! (field instanceof MaxSizable)) {
3370            log.warn("Skipping maximum length validator for field '" + field.getName() + "'; [database type='VARCHAR', field.type='" +  field.getType() + "' is not MaxSizable]"); 
3371            }
3372          else{
3373            VText vt = new VText((MaxSizable) field, "Not enough or too many characters");
3374            vt.setMaxSize(2147483647);
3375            }
3376          }
3377        }
3378    
3379      /** date (DATE); Nullable=true; AutoInc=false; MaxSize=13 */
3380      list = getFieldFromForm(form, "date_val", prefix, suffix, map, true);
3381      if (list.size() > 0) 
3382        { //add applicable automatic validators, empty if n/a
3383        for (int n = 0; n < list.size(); n++)
3384          {
3385          field = (Field) list.get(n);
3386          /* field is nullable, skipping non-nullability validation */
3387          }
3388        }
3389    
3390      /** time (TIME); Nullable=true; AutoInc=false; MaxSize=15 */
3391      list = getFieldFromForm(form, "time_val", prefix, suffix, map, true);
3392      if (list.size() > 0) 
3393        { //add applicable automatic validators, empty if n/a
3394        for (int n = 0; n < list.size(); n++)
3395          {
3396          field = (Field) list.get(n);
3397          /* field is nullable, skipping non-nullability validation */
3398          }
3399        }
3400    
3401      /** timestamp (TIMESTAMP); Nullable=true; AutoInc=false; MaxSize=29 */
3402      list = getFieldFromForm(form, "timestamp_val", prefix, suffix, map, true);
3403      if (list.size() > 0) 
3404        { //add applicable automatic validators, empty if n/a
3405        for (int n = 0; n < list.size(); n++)
3406          {
3407          field = (Field) list.get(n);
3408          /* field is nullable, skipping non-nullability validation */
3409          }
3410        }
3411    
3412      /** bit (BIT); Nullable=true; AutoInc=false; MaxSize=1 */
3413      list = getFieldFromForm(form, "bit_val", prefix, suffix, map, true);
3414      if (list.size() > 0) 
3415        { //add applicable automatic validators, empty if n/a
3416        for (int n = 0; n < list.size(); n++)
3417          {
3418          field = (Field) list.get(n);
3419          /* field is nullable, skipping non-nullability validation */
3420          }
3421        }
3422    
3423      /** _varchar (ARRAY); Nullable=true; AutoInc=false; MaxSize=10 */
3424      list = getFieldFromForm(form, "array_val", prefix, suffix, map, true);
3425      if (list.size() > 0) 
3426        { //add applicable automatic validators, empty if n/a
3427        for (int n = 0; n < list.size(); n++)
3428          {
3429          field = (Field) list.get(n);
3430          /* field is nullable, skipping non-nullability validation */
3431          }
3432        }
3433    
3434      /** bool (BIT); Nullable=true; AutoInc=false; MaxSize=1 */
3435      list = getFieldFromForm(form, "boolean_val", prefix, suffix, map, true);
3436      if (list.size() > 0) 
3437        { //add applicable automatic validators, empty if n/a
3438        for (int n = 0; n < list.size(); n++)
3439          {
3440          field = (Field) list.get(n);
3441          /* field is nullable, skipping non-nullability validation */
3442          }
3443        }
3444    
3445      /** bytea (BINARY); Nullable=true; AutoInc=false; MaxSize=2147483647 */
3446      list = getFieldFromForm(form, "varbinary_val", prefix, suffix, map, true);
3447      if (list.size() > 0) 
3448        { //add applicable automatic validators, empty if n/a
3449        for (int n = 0; n < list.size(); n++)
3450          {
3451          field = (Field) list.get(n);
3452          /* field is nullable, skipping non-nullability validation */
3453          }
3454        }
3455    
3456      /** json (OTHER); Nullable=true; AutoInc=false; MaxSize=2147483647 */
3457      list = getFieldFromForm(form, "json_val", prefix, suffix, map, true);
3458      if (list.size() > 0) 
3459        { //add applicable automatic validators, empty if n/a
3460        for (int n = 0; n < list.size(); n++)
3461          {
3462          field = (Field) list.get(n);
3463          /* field is nullable, skipping non-nullability validation */
3464          }
3465        }
3466    
3467      /** jsonb (OTHER); Nullable=true; AutoInc=false; MaxSize=2147483647 */
3468      list = getFieldFromForm(form, "jsonb_val", prefix, suffix, map, true);
3469      if (list.size() > 0) 
3470        { //add applicable automatic validators, empty if n/a
3471        for (int n = 0; n < list.size(); n++)
3472          {
3473          field = (Field) list.get(n);
3474          /* field is nullable, skipping non-nullability validation */
3475          }
3476        }
3477      }
3478    
3479    /** 
3480    Convenience method that calls {@link #addValidators(Form, String, String, Map)} with a 
3481    <tt>null</tt> prefix/suffix and the specified map
3482    */
3483    public static void addValidators(fc.web.forms.Form form, Map map) 
3484      {
3485      addValidators(form, null, null, map);
3486      }
3487    
3488    /** 
3489    Convenience method that calls {@link #addValidators(Form, String, String, Map)} with a 
3490    <tt>null</tt> prefix/suffix/map
3491    */
3492    public static void addValidators(fc.web.forms.Form form) 
3493      {
3494      addValidators(form, null, null, null);
3495      }
3496    
3497    /** 
3498    Convenience method that calls {@link #addValidators(Form, String, String, map)} with the 
3499    specified prefix and a <tt>null</tt> suffix/map
3500    */
3501    public static void addValidators(fc.web.forms.Form form, String prefix) 
3502      {
3503      addValidators(form, prefix, null, null);
3504      }
3505    
3506    /** 
3507    Validates a form field <i>if</i> it is filled by the user. Leaves empty fields alone.
3508    This is very useful for fields that are optional but must have the correct value when
3509    filled by the user
3510    */
3511    public static void addIfFilledValidators(Form form, String prefix) 
3512      {
3513      addValidators(form, prefix, null, null, true);
3514      }
3515    
3516    /** implementation helper method -- not for public use */
3517    static List getFieldFromForm(Form form, String colname, String prefix, String suffix, Map map, boolean warn)
3518      {
3519      Field field = null;
3520      List list = Form.empty_list;
3521      boolean getwhere = false;
3522      getwhere = false;
3523      String colname_in_form = colname;
3524    
3525      if (map != null) {
3526        String str = (String) map.get(colname);
3527        if (str != null) {
3528          prefix = null;  /*ignored when there is a mapping*/
3529          suffix = null;  /*ignored when there is a mapping*/
3530          colname_in_form = str; /* else if not in map, colname remains as-is*/
3531          }
3532        }
3533    
3534      if (prefix != null) 
3535        { 
3536        if (prefix.equals("*")) { 
3537          getwhere = true;
3538          }
3539        else{
3540          colname_in_form = prefix + colname_in_form;
3541          }
3542        }
3543    
3544      if (suffix != null) 
3545        {
3546        if (suffix.equals("*")) { 
3547          getwhere = true;
3548          }
3549        else{
3550          colname_in_form = colname_in_form + suffix;
3551          }
3552        }
3553    
3554      if (getwhere) { 
3555        list = form.getContaining(colname_in_form);
3556        if (list.size() == 0 && warn) warn(form, colname_in_form, suffix, prefix, map);
3557        return list;
3558        }
3559      else{
3560        //containsField() check prevents an un-necessary warning with form.get()
3561        if (! form.containsField(colname_in_form)) {
3562          if (warn) warn(form, colname_in_form, suffix, prefix, map);
3563          return list;
3564          }
3565        field = form.get(colname_in_form);
3566        list = new ArrayList();
3567        list.add(field);
3568        }
3569      return list;
3570      }
3571    
3572    private static final void warn(Form form, String name, String suffix, String prefix, Map map) {
3573      log.warn(form.getName(),": No automatic validators will be added for Field [",name,"]. This field does not exist in the front-end form. (this could be normal). suffix=["+suffix+"] prefix=["+prefix+"] map=", map);
3574      }
3575    
3576    /** 
3577    Validates the bean before saving it to the database. This
3578    method is called internally by the {@link save()} method
3579    before saving a new bean (i.e., inserting a new row) to the
3580    database.
3581    <p>
3582    The validation is somewhat basic and there can exist many
3583    constraints and conditions on the database that might results in a
3584    insert/update error anyway. But by doing some basic validation
3585    against some known constraints, we save a needless trip to the
3586    database.
3587    We check to see that: <ol>
3588    <li><i>non-nullable and non auto-increment</i> columns [and with no default
3589    column value in the database] are modified (via a set method) since these
3590    columns must have a explicitly set value.</li>
3591    <li>for non-nullable columns that hold non-primitive (i.e., Object)
3592    java types, the modified value for non-nullable columns is a
3593    non-null object. </li>
3594    </ol>
3595    */
3596    protected static void validateBeforeSaveNew(alltypes bean) throws ValidateException
3597      {
3598      boolean error = false;
3599      final StringBuffer buf = new StringBuffer("The following validation errors were found").append(IOUtil.LINE_SEP);
3600    
3601      //[id]=>is not nullable but has a default column value [nextval('alltypes_id_seq'::regclass)], no modification check necessary, skipping...
3602    
3603      //[smallint_val]=>nullable, no modification check necessary, skipping...
3604    
3605      if (! bean.isModified_int_val()) {
3606        error = true;
3607        buf.append("int_val was not set (this field is required in the database)").append(";current value=").append(bean.get_int_val()).append(IOUtil.LINE_SEP);
3608        }
3609      //int is primitive, skipping null test
3610    
3611      //[bigint_val]=>nullable, no modification check necessary, skipping...
3612    
3613      //[float_val]=>nullable, no modification check necessary, skipping...
3614    
3615      //[double_val]=>nullable, no modification check necessary, skipping...
3616    
3617      //[numeric_val]=>nullable, no modification check necessary, skipping...
3618    
3619      //[char_val]=>nullable, no modification check necessary, skipping...
3620    
3621      //[varchar_val]=>nullable, no modification check necessary, skipping...
3622    
3623      //[longvarchar_val]=>nullable, no modification check necessary, skipping...
3624    
3625      //[date_val]=>nullable, no modification check necessary, skipping...
3626    
3627      //[time_val]=>nullable, no modification check necessary, skipping...
3628    
3629      //[timestamp_val]=>nullable, no modification check necessary, skipping...
3630    
3631      //[bit_val]=>nullable, no modification check necessary, skipping...
3632    
3633      //[array_val]=>nullable, no modification check necessary, skipping...
3634    
3635      //[boolean_val]=>nullable, no modification check necessary, skipping...
3636    
3637      //[varbinary_val]=>nullable, no modification check necessary, skipping...
3638    
3639      //[json_val]=>nullable, no modification check necessary, skipping...
3640    
3641      //[jsonb_val]=>nullable, no modification check necessary, skipping...
3642      if (error) { 
3643        throw new ValidateException(buf.toString());
3644        }
3645      }
3646    
3647    /** 
3648    Validates the bean before saving it to the database. This method is
3649    called internally by the {@link save()} method before updating an
3650    existing bean (i.e., updating a row) in the database.
3651    <p>
3652    For <i>each modified column</i>, if that column is non-nullable in
3653    the database, then it must have a non-null value in the bean before
3654    it is saved. This check is only done for fields of
3655    <i>non</i>-primitive (Object) java types. [There is no way to ensure
3656    a non-null value for <i>primitive</i> types since all values
3657    [including 0] are non-null for those types].
3658    */
3659    protected static void validateBeforeSaveUpdate(alltypes bean) throws ValidateException
3660      {
3661      boolean error = false;
3662      final StringBuffer buf = new StringBuffer("The following validation errors were found").append(IOUtil.LINE_SEP);
3663    
3664      //[id]=>auto-increment, no modification check necessary, skipping...
3665      //[smallint_val]=>nullable, no modification check necessary, skipping...
3666      if (bean.isModified_int_val()) {
3667        //int is primitive, skipping null test
3668        }
3669      //[bigint_val]=>nullable, no modification check necessary, skipping...
3670      //[float_val]=>nullable, no modification check necessary, skipping...
3671      //[double_val]=>nullable, no modification check necessary, skipping...
3672      //[numeric_val]=>nullable, no modification check necessary, skipping...
3673      //[char_val]=>nullable, no modification check necessary, skipping...
3674      //[varchar_val]=>nullable, no modification check necessary, skipping...
3675      //[longvarchar_val]=>nullable, no modification check necessary, skipping...
3676      //[date_val]=>nullable, no modification check necessary, skipping...
3677      //[time_val]=>nullable, no modification check necessary, skipping...
3678      //[timestamp_val]=>nullable, no modification check necessary, skipping...
3679      //[bit_val]=>nullable, no modification check necessary, skipping...
3680      //[array_val]=>nullable, no modification check necessary, skipping...
3681      //[boolean_val]=>nullable, no modification check necessary, skipping...
3682      //[varbinary_val]=>nullable, no modification check necessary, skipping...
3683      //[json_val]=>nullable, no modification check necessary, skipping...
3684      //[jsonb_val]=>nullable, no modification check necessary, skipping...
3685      if (error) { 
3686        throw new ValidateException(buf.toString());
3687        }
3688      }
3689    }