예제 #1
0
        public IDataReader ExecuteReader(CommandBehavior behavior, bool want_results, out int rows_affected)
        {
            Prepare();

            // The SQL string may contain multiple sql commands, so the main
            // thing to do is have Sqlite iterate through the commands.
            // If want_results, only the last command is returned as a
            // DataReader.  Otherwise, no command is returned as a
            // DataReader.

            //IntPtr psql; // pointer to SQL command

            // Sqlite 2 docs say this: By default, SQLite assumes that all data uses a fixed-size 8-bit
            // character (iso8859).  But if you give the --enable-utf8 option to the configure script, then the
            // library assumes UTF-8 variable sized characters. This makes a difference for the LIKE and GLOB
            // operators and the LENGTH() and SUBSTR() functions. The static string sqlite_encoding will be set
            // to either "UTF-8" or "iso8859" to indicate how the library was compiled. In addition, the sqlite.h
            // header file will define one of the macros SQLITE_UTF8 or SQLITE_ISO8859, as appropriate.
            //
            // We have no way of knowing whether Sqlite 2 expects ISO8859 or UTF-8, but ISO8859 seems to be the
            // default.  Therefore, we need to use an ISO8859(-1) compatible encoding, like ANSI.
            // OTOH, the user may want to specify the encoding of the bytes stored in the database, regardless
            // of what Sqlite is treating them as,

            // For Sqlite 3, we use the UTF-16 prepare function, so we need a UTF-16 string.

            //if (parent_conn.Version == 2)
            //    psql = Sqlite.StringToHeap(sql.Trim(), parent_conn.Encoding);
            //else
            //    var psql = Marshal.StringToHGlobalUni(sql.Trim());

            string queryval = sql.Trim();

            //string pzTail = sql.Trim();
            //IntPtr pzTail = IntPtr.Zero;
            Sqlite3.Result errMsgPtr;

            (parent_conn as SqliteConnection).StartExec();

            rows_affected = 0;

            try {
                while (true)
                {
                    IntPtr pStmt = IntPtr.Zero;

                    //queryval = pzTail;
                    pStmt = Sqlite3.Prepare2((parent_conn as SqliteConnection).Handle2, ref queryval);
                    //GetNextStatement(queryval, ref pzTail, ref pStmt);

                    if (pStmt == null)
                    {
                        throw new Exception();
                    }

                    // pzTail is positioned after the last byte in the
                    // statement, which will be the NULL character if
                    // this was the last statement.

                    //bool last = pzTail == IntPtr.Zero;
                    bool last = queryval.Length == 0;

                    try
                    {
                        if ((parent_conn as SqliteConnection).Version == 3)
                        {
                            BindParameters3(pStmt);
                        }

                        if (last && want_results)
                        {
                            return(new SqliteDataReader(this, pStmt, (parent_conn as SqliteConnection).Version));
                        }

                        ExecuteStatement(pStmt);

                        if (last)                         // rows_affected is only used if !want_results
                        {
                            rows_affected = NumChanges();
                        }
                    } finally {
                        //if (parent_conn.Version == 3)
                        errMsgPtr = Sqlite3.Finalize(pStmt);
                        //else
                        //	Sqlite.sqlite_finalize (pStmt, out errMsgPtr);
                    }

                    if (last)
                    {
                        break;
                    }
                }

                return(null);
            } finally {
                (parent_conn as SqliteConnection).EndExec();
                //Marshal.FreeHGlobal (psql);
            }
        }