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