All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ziclix.python.sql.PyCursor Maven / Gradle / Ivy

Go to download

Jython is an implementation of the high-level, dynamic, object-oriented language Python written in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run Python on any Java platform.

There is a newer version: 2.7.4
Show newest version

/*
 * Jython Database Specification API 2.0
 *
 * $Id: PyCursor.java 3248 2007-05-30 05:19:19Z cgroves $
 *
 * Copyright (c) 2001 brian zimmer 
 *
 */
package com.ziclix.python.sql;

import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.List;
import org.python.core.ClassDictInit;
import org.python.core.Py;
import org.python.core.PyBuiltinMethodSet;
import org.python.core.PyClass;
import org.python.core.PyDictionary;
import org.python.core.PyException;
import org.python.core.PyInteger;
import org.python.core.PyList;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.core.PyTuple;
import com.ziclix.python.sql.util.PyArgParser;

/**
 * These objects represent a database cursor, which is used to manage the
 * context of a fetch operation.
 *
 * @author brian zimmer
 * @author last revised by $Author: cgroves $
 * @version $Revision: 3248 $
 */
public class PyCursor extends PyObject implements ClassDictInit, WarningListener {

  /** Field fetch */
  protected Fetch fetch;

  /** Field closed */
  private boolean closed;

  /** Field arraysize */
  protected int arraysize;

  /** Field softspace */
  protected int softspace;

  /** Field rsType */
  protected PyObject rsType;

  /** Field rsConcur */
  protected PyObject rsConcur;

  /** Field warnings */
  protected PyObject warnings;

  /** Field warnings */
  protected PyObject lastrowid;

  /** Field updatecount */
  protected PyObject updatecount;

  /** Field dynamicFetch */
  protected boolean dynamicFetch;

  /** Field connection */
  protected PyConnection connection;

  /** Field datahandler */
  protected DataHandler datahandler;

  /** Field statement */
  protected PyStatement statement;

  // they are stateless instances, so we only need to instantiate it once
  private static final DataHandler DATAHANDLER = DataHandler.getSystemDataHandler();

  /**
   * Create the cursor with a static fetch.
   *
   * @param connection
   */
  PyCursor(PyConnection connection) {
    this(connection, false);
  }

  /**
   * Create the cursor, optionally choosing the type of fetch (static or dynamic).
   * If dynamicFetch is true, then use a dynamic fetch.
   *
   * @param connection
   * @param dynamicFetch
   */
  PyCursor(PyConnection connection, boolean dynamicFetch) {

    this.arraysize = 1;
    this.softspace = 0;
    this.closed = false;
    this.rsType = Py.None;
    this.rsConcur = Py.None;
    this.connection = connection;
    this.datahandler = DATAHANDLER;
    this.dynamicFetch = dynamicFetch;

    // constructs the appropriate Fetch among other things
    this.clear();
  }

  /**
   * Create the cursor, optionally choosing the type of fetch (static or dynamic).
   * If dynamicFetch is true, then use a dynamic fetch.
   * rsType and rsConcur are used to create the Statement if both are non-None
   *
   * @param connection
   * @param dynamicFetch
   * @param rsType
   * @param rsConcur
   */
  PyCursor(PyConnection connection, boolean dynamicFetch, PyObject rsType, PyObject rsConcur) {

    this(connection, dynamicFetch);

    this.rsType = rsType;
    this.rsConcur = rsConcur;
  }

  /** Field __class__ */
  public static PyClass __class__;

  /**
   * Method getPyClass
   *
   * @return PyClass
   *
   */
  protected PyClass getPyClass() {
    return __class__;
  }

  /** Field __methods__ */
  protected static PyList __methods__;

  /** Field __members__ */
  protected static PyList __members__;

  static {
    PyObject[] m = new PyObject[9];

    m[0] = new PyString("close");
    m[1] = new PyString("execute");
    m[2] = new PyString("executemany");
    m[3] = new PyString("fetchone");
    m[4] = new PyString("fetchall");
    m[5] = new PyString("fetchmany");
    m[6] = new PyString("callproc");
    m[7] = new PyString("next");
    m[8] = new PyString("write");
    __methods__ = new PyList(m);
    m = new PyObject[11];
    m[0] = new PyString("arraysize");
    m[1] = new PyString("rowcount");
    m[2] = new PyString("rownumber");
    m[3] = new PyString("description");
    m[4] = new PyString("datahandler");
    m[5] = new PyString("warnings");
    m[6] = new PyString("lastrowid");
    m[7] = new PyString("updatecount");
    m[8] = new PyString("softspace");
    m[9] = new PyString("closed");
    m[10] = new PyString("connection");
    __members__ = new PyList(m);
  }

  /**
   * String representation of the object.
   *
   * @return a string representation of the object.
   */
  public String toString() {
    return "";
  }

  /**
   * Sets the attribute name to value.
   *
   * @param name
   * @param value
   */
  public void __setattr__(String name, PyObject value) {

    if ("arraysize".equals(name)) {
      this.arraysize = ((PyInteger)value.__int__()).getValue();
    } else if ("softspace".equals(name)) {
      this.softspace = ((PyInteger)value.__int__()).getValue();
    } else if ("datahandler".equals(name)) {
      this.datahandler = (DataHandler)value.__tojava__(DataHandler.class);
    } else {
      super.__setattr__(name, value);
    }
  }

  /**
   * Gets the value of the attribute name.
   *
   * @param name
   * @return the attribute for the given name
   */
  public PyObject __findattr__(String name) {

    if ("arraysize".equals(name)) {
      return Py.newInteger(arraysize);
    } else if ("softspace".equals(name)) {
      return Py.newInteger(softspace);
    } else if ("__methods__".equals(name)) {
      return __methods__;
    } else if ("__members__".equals(name)) {
      return __members__;
    } else if ("description".equals(name)) {
      return this.fetch.description;
    } else if ("rowcount".equals(name)) {
      return Py.newInteger(this.fetch.rowcount);
    } else if ("rownumber".equals(name)) {
      int rn = this.fetch.rownumber;
      return (rn < 0) ? Py.None : Py.newInteger(rn);
    } else if ("warnings".equals(name)) {
      return warnings;
    } else if ("lastrowid".equals(name)) {
      return lastrowid;
    } else if ("updatecount".equals(name)) {
      return updatecount;
    } else if ("datahandler".equals(name)) {
      return Py.java2py(this.datahandler);
    } else if ("dynamic".equals(name)) {
      return this.dynamicFetch ? Py.One : Py.Zero;
    } else if ("connection".equals(name)) {
      return this.connection;
    } else if ("closed".equals(name)) {
      return Py.newBoolean(closed);
    } else if ("callproc".equals(name)) {
      try {
        // dynamically decide on the the attribute based on the driver
        if (!getMetaData().supportsStoredProcedures()) {
            return null;
        }
      } catch (Throwable t) {}
    }

    return super.__findattr__(name);
  }

  /**
   * Initializes the object's namespace.
   *
   * @param dict
   */
  static public void classDictInit(PyObject dict) {

    dict.__setitem__("__version__", Py.newString("$Revision: 3248 $").__getslice__(Py.newInteger(11), Py.newInteger(-2), null));
    dict.__setitem__("fetchmany", new CursorFunc("fetchmany", 0, 0, 1, "fetch specified number of rows"));
    dict.__setitem__("close", new CursorFunc("close", 1, 0, "close the cursor"));
    dict.__setitem__("fetchall", new CursorFunc("fetchall", 2, 0, "fetch all results"));
    dict.__setitem__("fetchone", new CursorFunc("fetchone", 3, 0, "fetch the next result"));
    dict.__setitem__("nextset", new CursorFunc("nextset", 4, 0, "return next set or None"));
    dict.__setitem__("execute", new CursorFunc("execute", 5, 1, 4, "execute the sql expression"));
    dict.__setitem__("setinputsizes", new CursorFunc("setinputsizes", 6, 1, "not implemented"));
    dict.__setitem__("setoutputsize", new CursorFunc("setoutputsize", 7, 1, 2, "not implemented"));
    dict.__setitem__("callproc", new CursorFunc("callproc", 8, 1, 4, "executes a stored procedure"));
    dict.__setitem__("executemany", new CursorFunc("executemany", 9, 1, 3, "execute sql with the parameter list"));
    dict.__setitem__("scroll", new CursorFunc("scroll", 10, 1, 2, "scroll the cursor in the result set to a new position according to mode"));
    dict.__setitem__("write", new CursorFunc("write", 11, 1, "execute the sql written to this file-like object"));
    dict.__setitem__("prepare", new CursorFunc("prepare", 12, 1, "prepare the sql statement for later execution"));

    // hide from python
    dict.__setitem__("classDictInit", null);
    dict.__setitem__("toString", null);
    dict.__setitem__("getDataHandler", null);
    dict.__setitem__("warning", null);
    dict.__setitem__("fetch", null);
    dict.__setitem__("statement", null);
    dict.__setitem__("dynamicFetch", null);
    dict.__setitem__("getPyClass", null);
    dict.__setitem__("rsConcur", null);
    dict.__setitem__("rsType", null);
  }

  /**
   * Delete the cursor.
   *
   */
  public void __del__() {
    close();
  }

  /**
   * Close the cursor now (rather than whenever __del__ is called).
   * The cursor will be unusable from this point forward; an Error
   * (or subclass) exception will be raised if any operation is
   * attempted with the cursor.
   *
   */
  public void close() {

    try {
      this.clear();
      this.connection.remove(this);
    } finally {
      this.closed = true;
    }
  }

  /**
   * Returns an iteratable object.
   *
   * @return PyObject
   *
   * @since Jython 2.2, DB API 2.0+
   */
  public PyObject __iter__() {
    return this;
  }

  /**
   * Returns the next row from the currently executing SQL statement
   * using the same semantics as .fetchone().  A StopIteration
   * exception is raised when the result set is exhausted for Python
   * versions 2.2 and later.
   *
   * @return PyObject
   *
   * @since Jython 2.2, DB API 2.0+
   */
  public PyObject next() {
    PyObject row = __iternext__();
    if (row == null) {
      throw Py.StopIteration("");
    }
    return row;
  }

  /**
   * Return the next element of the sequence that this is an iterator
   * for. Returns null when the end of the sequence is reached.
   *
   * @since Jython 2.2
   *
   * @return PyObject
   */
  public PyObject __iternext__() {
    PyObject row = fetchone();
    return row.__nonzero__() ? row : null;
  }

  /**
   * Return ths DatabaseMetaData for the current connection.
   *
   * @return DatabaseMetaData
   *
   * @throws SQLException
   */
  protected DatabaseMetaData getMetaData() throws SQLException {
    return this.connection.connection.getMetaData();
  }

  /**
   * Return the currently bound DataHandler.
   *
   * @return DataHandler
   */
  public DataHandler getDataHandler() {
    return this.datahandler;
  }

  /**
   * Prepare a statement ready for executing.
   *
   * @param sql the sql to execute or a prepared statement
   * @param maxRows max number of rows to be returned
   * @param prepared if true, prepare the statement, otherwise create a normal statement
   *
   * @return PyStatement
   */
  private PyStatement prepareStatement(PyObject sql, PyObject maxRows, boolean prepared) {

    PyStatement stmt = null;

    if (sql == Py.None) {
      return null;
    }

    try {
      if (sql instanceof PyStatement) {
        stmt = (PyStatement)sql;
      } else {
        Statement sqlStatement = null;
        String sqlString = sql.__str__().toString();

        if (sqlString.trim().length() == 0) {
          return null;
        }

        boolean normal = ((this.rsType == Py.None) && (this.rsConcur == Py.None));

        if (normal) {
          if (prepared) {
            sqlStatement = this.connection.connection.prepareStatement(sqlString);
          } else {
            sqlStatement = this.connection.connection.createStatement();
          }
        } else {
          int t = ((PyInteger)this.rsType.__int__()).getValue();
          int c = ((PyInteger)this.rsConcur.__int__()).getValue();

          if (prepared) {
            sqlStatement = this.connection.connection.prepareStatement(sqlString, t, c);
          } else {
            sqlStatement = this.connection.connection.createStatement(t, c);
          }
        }

        int style = prepared ? PyStatement.STATEMENT_PREPARED : PyStatement.STATEMENT_STATIC;

        stmt = new PyStatement(sqlStatement, sqlString, style);
      }

      if (maxRows != Py.None) {
        stmt.statement.setMaxRows(((PyInteger)maxRows.__int__()).getValue());
      }
    } catch (AbstractMethodError e) {
      throw zxJDBC.makeException(zxJDBC.NotSupportedError, zxJDBC.getString("nodynamiccursors"));
    } catch (PyException e) {
      throw e;
    } catch (Throwable e) {
      throw zxJDBC.makeException(e);
    }

    return stmt;
  }

  /**
   * This method is optional since not all databases provide stored procedures.
   *
   * Call a stored database procedure with the given name. The sequence of parameters
   * must contain one entry for each argument that the procedure expects. The result of
   * the call is returned as modified copy of the input sequence. Input parameters are
   * left untouched, output and input/output parameters replaced with possibly new values.
   *
   * The procedure may also provide a result set as output. This must then be made available
   * through the standard fetchXXX() methods.
   *
   * @param name
   * @param params
   * @param bindings
   * @param maxRows
   */
  public void callproc(PyObject name, final PyObject params, PyObject bindings, PyObject maxRows) {

    this.clear();

    try {
      if (getMetaData().supportsStoredProcedures()) {
        if (isSeqSeq(params)) {
          throw zxJDBC.makeException(zxJDBC.NotSupportedError, "sequence of sequences is not supported");
        }

        final Procedure procedure = datahandler.getProcedure(this, name);
        Statement stmt = procedure.prepareCall(this.rsType, this.rsConcur);

        if (maxRows != Py.None) {
          stmt.setMaxRows(((PyInteger)maxRows.__int__()).getValue());
        }

        // get the bindings per the stored proc spec
        PyDictionary callableBindings = new PyDictionary();

        procedure.normalizeInput(params, callableBindings);

        // overwrite with any user specific bindings
        if (bindings instanceof PyDictionary) {
          callableBindings.update((PyDictionary)bindings);
        }

        this.statement = new PyStatement(stmt, procedure);

        this.execute(params, callableBindings);
      } else {
        throw zxJDBC.makeException(zxJDBC.NotSupportedError, zxJDBC.getString("noStoredProc"));
      }
    } catch (PyException e) {
      throw e;
    } catch (Throwable e) {
      throw zxJDBC.makeException(e);
    } finally {
      if (this.statement != null) {

        // close what we opened
        this.statement.close();
      }
    }
  }

  /**
   * Prepare a database operation (query or command) and then execute it against all
   * parameter sequences or mappings found in the sequence seq_of_parameters.
   * Modules are free to implement this method using multiple calls to the execute()
   * method or by using array operations to have the database process the sequence as
   * a whole in one call.
   *
   * The same comments as for execute() also apply accordingly to this method.
   *
   * Return values are not defined.
   *
   * @param sql
   * @param params
   * @param bindings
   * @param maxRows
   */
  public void executemany(PyObject sql, PyObject params, PyObject bindings, PyObject maxRows) {
    execute(sql, params, bindings, maxRows);
  }

  /**
   * Prepare and execute a database operation (query or command).
   * Parameters may be provided as sequence or mapping and will
   * be bound to variables in the operation. Variables are specified
   * in a database-specific notation (see the module's paramstyle
   * attribute for details).
   *
   * A reference to the operation will be retained by the cursor.
   * If the same operation object is passed in again, then the cursor
   * can optimize its behavior. This is most effective for algorithms
   * where the same operation is used, but different parameters are
   * bound to it (many times).
   *
   * For maximum efficiency when reusing an operation, it is best to
   * use the setinputsizes() method to specify the parameter types and
   * sizes ahead of time. It is legal for a parameter to not match the
   * predefined information; the implementation should compensate, possibly
   * with a loss of efficiency.
   *
   * The parameters may also be specified as list of tuples to e.g. insert
   * multiple rows in a single operation, but this kind of usage is
   * deprecated: executemany() should be used instead.
   *
   * Return values are not defined.
   *
   * @param sql sql string or prepared statement
   * @param params params for a prepared statement
   * @param bindings dictionary of (param index : SQLType binding)
   * @param maxRows integer value of max rows
   */
  public void execute(final PyObject sql, PyObject params, PyObject bindings, PyObject maxRows) {

    this.clear();

    boolean hasParams = hasParams(params);
    PyStatement stmt = this.prepareStatement(sql, maxRows, hasParams);

    if (stmt == null) {
      return;
    }

    this.statement = stmt;

    try {
      synchronized (this.statement) {
        if (hasParams) {

          // if we have a sequence of sequences, let's run through them and finish
          if (isSeqSeq(params)) {

            // [(3, 4)] or [(3, 4), (5, 6)]
            for (int i = 0, len = params.__len__(); i < len; i++) {
              PyObject param = params.__getitem__(i);

              this.execute(param, bindings);
            }
          } else {
            this.execute(params, bindings);
          }
        } else {

          // execute the sql string straight up
          this.execute(Py.None, Py.None);
        }
      }
    } catch (PyException e) {
      throw e;
    } catch (Throwable e) {
      throw zxJDBC.makeException(e);
    } finally {
      if (this.statement != null) {

        // only close static, single-use statements
        if (!(sql instanceof PyStatement) && (!this.dynamicFetch)) {
          this.statement.close();
        }
      }
    }
  }

  /**
   * Execute the current sql statement.  Some generic functionality such
   * as updating the lastrowid and updatecount occur as well.
   */
  protected void execute(PyObject params, PyObject bindings) {

    try {
      Statement stmt = this.statement.statement;

      this.datahandler.preExecute(stmt);

      // this performs the SQL execution and fetch per the Statement type
      this.statement.execute(this, params, bindings);

      this.lastrowid = this.datahandler.getRowId(stmt);

      int uc = stmt.getUpdateCount();

      this.updatecount = (uc < 0) ? Py.None : Py.newInteger(uc);

      warning(new WarningEvent(this, stmt.getWarnings()));
      this.datahandler.postExecute(stmt);
    } catch (PyException e) {
      throw e;
    } catch (Throwable e) {
      throw zxJDBC.makeException(e);
    }
  }

  /**
   * Fetch the next row of a query result set, returning a single sequence,
   * or None when no more data is available.
   *
   * An Error (or subclass) exception is raised if the previous call to
   * executeXXX() did not produce any result set or no call was issued yet.
   *
   * @return a single sequence from the result set, or None when no more data is available
   */
  public PyObject fetchone() {
    return this.fetch.fetchone();
  }

  /**
   * Fetch all (remaining) rows of a query result, returning them as a sequence
   * of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute
   * can affect the performance of this operation.
   *
   * An Error (or subclass) exception is raised if the previous call to executeXXX()
   * did not produce any result set or no call was issued yet.
   *
   * @return a sequence of sequences from the result set, or an empty sequence when
   *         no more data is available
   */
  public PyObject fetchall() {
    return this.fetch.fetchall();
  }

  /**
   * Fetch the next set of rows of a query result, returning a sequence of
   * sequences (e.g. a list of tuples). An empty sequence is returned when
   * no more rows are available.
   *
   * The number of rows to fetch per call is specified by the parameter. If
   * it is not given, the cursor's arraysize determines the number of rows
   * to be fetched. The method should try to fetch as many rows as indicated
   * by the size parameter. If this is not possible due to the specified number
   * of rows not being available, fewer rows may be returned.
   *
   * An Error (or subclass) exception is raised if the previous call to executeXXX()
   * did not produce any result set or no call was issued yet.
   *
   * Note there are performance considerations involved with the size parameter.
   * For optimal performance, it is usually best to use the arraysize attribute.
   * If the size parameter is used, then it is best for it to retain the same value
   * from one fetchmany() call to the next.
   *
   * @param size
   * @return a sequence of sequences from the result set, or an empty sequence when
   *         no more data is available
   */
  public PyObject fetchmany(int size) {
    return this.fetch.fetchmany(size);
  }

  /**
   * Move the result pointer to the next set if available.
   *
   * @return true if more sets exist, else None
   */
  public PyObject nextset() {
    return this.fetch.nextset();
  }

  /**
   * Prepare a sql statement for later execution.
   *
   * @param sql The sql string to be prepared.
   *
   * @return A prepared statement usable with .executeXXX()
   */
  public PyStatement prepare(PyObject sql) {

    PyStatement s = this.prepareStatement(sql, Py.None, true);

    // add to the set of statements which are leaving our control
    this.connection.add(s);

    return s;
  }

  /**
   * Scroll the cursor in the result set to a new position according
   * to mode.
   *
   * If mode is 'relative' (default), value is taken as offset to
   * the current position in the result set, if set to 'absolute',
   * value states an absolute target position.
   *
   * An IndexError should be raised in case a scroll operation would
   * leave the result set. In this case, the cursor position is left
   * undefined (ideal would be to not move the cursor at all).
   *
   * Note: This method should use native scrollable cursors, if
   * available, or revert to an emulation for forward-only
   * scrollable cursors. The method may raise NotSupportedErrors to
   * signal that a specific operation is not supported by the
   * database (e.g. backward scrolling).
   *
   *
   * @param value
   * @param mode
   *
   */
  public void scroll(int value, String mode) {
    this.fetch.scroll(value, mode);
  }

  /**
   * Adds a warning to the tuple and will follow the chain as necessary.
   *
   * @param event
   */
  public void warning(WarningEvent event) {

    if (this.warnings == Py.None) {
      this.warnings = new PyList();
    }

    SQLWarning warning = event.getWarning();
    while(warning != null) {

      PyObject[] warn = new PyObject[] {
        // there are three parts: (reason, state, vendorCode)
        Py.java2py(warning.getMessage()),
        Py.java2py(warning.getSQLState()),
        Py.newInteger(warning.getErrorCode())
      };

      // add the warning to the list
      ((PyList)this.warnings).append(new PyTuple(warn));

      warning = warning.getNextWarning();
    }
  }

  /**
   * Resets the cursor state. This includes flushing the warnings
   * and any previous results.
   *
   */
  protected void clear() {

    if (closed) {
      throw zxJDBC.makeException(zxJDBC.ProgrammingError, "cursor is closed");
    }

    this.warnings = Py.None;
    this.lastrowid = Py.None;
    this.updatecount = Py.newInteger(-1);

    try {
      this.fetch.close();
    } catch (Throwable e) {}
    finally {
      this.fetch = Fetch.newFetch(this.datahandler, this.dynamicFetch);

      this.fetch.addWarningListener(this);
    }

    if (this.statement != null) {

      // we can't close a dynamic fetch statement until everything has been
      // consumed so the only time we can clean up is now
      // but if this is a previously prepared statement we don't want to close
      // it underneath someone; we can check this by looking in the set
      try {
        if (this.dynamicFetch && (!this.connection.contains(this.statement))) {
          this.statement.close();
        }
      } finally {
        this.statement = null;
      }
    }
  }

  /**
   * Method isSeq
   *
   * @param object
   *
   * @return true for any PyList, PyTuple or java.util.List
   *
   */
  public static boolean isSeq(PyObject object) {

    if ((object == null) || (object == Py.None)) {
      return false;
    }

    if (object.__tojava__(List.class) != Py.NoConversion) {
      return true;
    }

    // originally checked for __getitem__ and __len__, but this is true for PyString
    // and we don't want to insert one character at a time
    return (object instanceof PyList) || (object instanceof PyTuple);
  }

  /**
   * Method hasParams
   *
   * @param params
   *
   * @return boolean
   *
   */
  public static boolean hasParams(PyObject params) {
    if(Py.None == params) {
      return false;
    }

    boolean isSeq = isSeq(params);
    // the optional argument better be a sequence
    if (!isSeq) {
      throw zxJDBC.makeException(zxJDBC.ProgrammingError, zxJDBC.getString("optionalSecond"));
    }
    return params.__len__() > 0;
  }

  /**
   * Method isSeqSeq
   *
   * @param object
   *
   * @return true is a sequence of sequences
   *
   */
  public static boolean isSeqSeq(PyObject object) {

    if (isSeq(object) && (object.__len__() > 0)) {
      for (int i = 0; i < object.__len__(); i++) {
        if (!isSeq(object.__finditem__(i))) {
          return false;
        }
      }
      return true;
    }
    return false;
  }
}

class CursorFunc extends PyBuiltinMethodSet {
  CursorFunc(String name, int index, int argcount, String doc) {
    this(name, index, argcount, argcount, doc);
  }
  CursorFunc(String name, int index, int minargs, int maxargs, String doc) {
    super(name, index, minargs, maxargs, doc, PyCursor.class);
  }

  public PyObject __call__() {
    PyCursor cursor = (PyCursor)__self__;
    switch (index) {
      case 0 :
        return cursor.fetchmany(cursor.arraysize);
      case 1 :
        cursor.close();
        return Py.None;
      case 2 :
        return cursor.fetchall();
      case 3 :
        return cursor.fetchone();
      case 4 :
        return cursor.nextset();
      default :
        throw info.unexpectedCall(0, false);
    }
  }

  public PyObject __call__(PyObject arg) {
    PyCursor cursor = (PyCursor)__self__;
    switch (index) {
      case 0 :
        return cursor.fetchmany(((PyInteger)arg.__int__()).getValue());
      case 5 :
        cursor.execute(arg, Py.None, Py.None, Py.None);
        return Py.None;
      case 6 :
      case 7 :
        return Py.None;
      case 8 :
        cursor.callproc(arg, Py.None, Py.None, Py.None);
        return Py.None;
      case 9 :
        cursor.executemany(arg, Py.None, Py.None, Py.None);
        return Py.None;
      case 10 :
        cursor.scroll(((PyInteger)arg.__int__()).getValue(), "relative");
        return Py.None;
      case 11 :
        cursor.execute(arg, Py.None, Py.None, Py.None);
        return Py.None;
      case 12 :
        return cursor.prepare(arg);
      default :
        throw info.unexpectedCall(1, false);
    }
  }

  public PyObject __call__(PyObject arga, PyObject argb) {
    PyCursor cursor = (PyCursor)__self__;
    switch (index) {
      case 5 :
        cursor.execute(arga, argb, Py.None, Py.None);
        return Py.None;
      case 7 :
        return Py.None;
      case 8 :
        cursor.callproc(arga, argb, Py.None, Py.None);
        return Py.None;
      case 9 :
        cursor.executemany(arga, argb, Py.None, Py.None);
        return Py.None;
      case 10 :
        cursor.scroll(((PyInteger)arga.__int__()).getValue(), argb.toString());
        return Py.None;
      default :
        throw info.unexpectedCall(2, false);
    }
  }

  public PyObject __call__(PyObject arga, PyObject argb, PyObject argc) {
    PyCursor cursor = (PyCursor)__self__;
    switch (index) {
      case 5 :
        cursor.execute(arga, argb, argc, Py.None);
        return Py.None;
      case 8 :
        cursor.callproc(arga, argb, argc, Py.None);
        return Py.None;
      case 9 :
        cursor.executemany(arga, argb, argc, Py.None);
        return Py.None;
      default :
        throw info.unexpectedCall(3, false);
    }
  }

  public PyObject __call__(PyObject[] args, String[] keywords) {

    PyCursor cursor = (PyCursor)__self__;
    PyArgParser parser = new PyArgParser(args, keywords);
    PyObject sql = parser.arg(0);
    PyObject params = parser.kw("params", Py.None);
    PyObject bindings = parser.kw("bindings", Py.None);
    PyObject maxrows = parser.kw("maxrows", Py.None);

    params = (parser.numArg() >= 2) ? parser.arg(1) : params;
    bindings = (parser.numArg() >= 3) ? parser.arg(2) : bindings;
    maxrows = (parser.numArg() >= 4) ? parser.arg(3) : maxrows;

    switch (index) {
      case 5 :
        cursor.execute(sql, params, bindings, maxrows);
        return Py.None;
      case 8 :
        cursor.callproc(sql, params, bindings, maxrows);
        return Py.None;
      case 9 :
        cursor.executemany(sql, params, bindings, maxrows);
        return Py.None;
      default :
        throw info.unexpectedCall(args.length, true);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy