summaryrefslogtreecommitdiffstats
path: root/kexi/plugins/scripting/kexidb/kexidbcursor.h
blob: 6ff094ae78658e86cb4cf3eddc56ea7d561d5a0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/***************************************************************************
 * kexidbcursor.h
 * This file is part of the KDE project
 * copyright (C)2004-2005 by Sebastian Sauer (mail@dipe.org)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 * You should have received a copy of the GNU Library General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 ***************************************************************************/

#ifndef KROSS_KEXIDB_KEXIDBCURSOR_H
#define KROSS_KEXIDB_KEXIDBCURSOR_H

#include <tqstring.h>

#include <api/object.h>
#include <api/variant.h>
#include <api/list.h>
#include <api/class.h>

#include <kexidb/cursor.h>
#include <kexidb/roweditbuffer.h>

namespace Kross { namespace KexiDB {

    // Forward declaration.
    class KexiDBConnection;

    /**
     * The cursor provides a control structure for the successive traversal
     * of records in a result set as returned e.g. by a query.
     *
     * Example (in Python) that shows how to iterate over the result of a query;
     * @code
     * # Once we have a KexiDBConnection object we are able to execute a query string and get a cursor as result.
     * cursor = connection.executeQueryString("SELECT * from emp")
     * # Let's check if the query was successfully.
     * if not cursor: raise("Query failed")
     * # Walk through all items in the table.
     * while(not cursor.eof()):
     *     # Iterate over the fields the record has.
     *     for i in range( cursor.fieldCount() ):
     *         # Print some information.
     *         print "%s %s %s" % (cursor.at(), i, cursor.value(i))
     *     # and move on to the next record.
     *     cursor.moveNext()
     * @endcode
     *
     * Example (in Python) that shows how to use a cursor to strip
     * all whitespaces at the beginning and the end from the values
     * in a table;
     * @code
     * import krosskexidb
     * drivermanager = krosskexidb.DriverManager()
     * connectiondata = drivermanager.createConnectionDataByFile("/home/me/kexiprojectfile.kexi")
     * driver = drivermanager.driver( connectiondata.driverName() )
     * connection = driver.createConnection(connectiondata)
     * if not connection.connect(): raise "Failed to connect"
     * if not connection.useDatabase( connectiondata.databaseName() ):
     *     if not connection.useDatabase( connectiondata.fileName() ):
     *         raise "Failed to use database"
     *
     * table = connection.tableSchema("emp")
     * query = table.query()
     * cursor = connection.executeQuerySchema(query)
     * if not cursor: raise("Query failed")
     * while(not cursor.eof()):
     *     for i in range( cursor.fieldCount() ):
     *         v = str( cursor.value(i) )
     *         if v.startswith(' ') or v.endswith(' '):
     *             cursor.setValue(i, v.strip())
     *     cursor.moveNext()
     * if not cursor.save(): raise "Failed to save changes"
     * @endcode
     */
    class KexiDBCursor : public Kross::Api::Class<KexiDBCursor>
    {
        public:
            KexiDBCursor(::KexiDB::Cursor* cursor);
            virtual ~KexiDBCursor();
            virtual const TQString getClassName() const;

        private:

            /** Opens the cursor. */
            bool open();
            /** Returns true if the cursor is opened else false. */
            bool isOpened();
            /** Closes and then opens again the same cursor. */
            bool reopen();
            /** Closes previously opened cursor. */
            bool close();

            /** Moves current position to the first record and retrieves it. */
            bool moveFirst();
            /** Moves current position to the last record and retrieves it. */
            bool moveLast();
            /** Moves current position to the previous record and retrieves it. */
            bool movePrev();
            /** Moves current position to the next record and retrieves it. */
            bool moveNext();

            /** Returns true if current position is before first record. */
            bool bof();
            /** Returns true if current position is after last record. */
            bool eof();

            /** Returns current internal position of the cursor's query. Records
            are numbered from 0; the value -1 means that the cursor does not
            point to a valid record. */
            TQ_LLONG at();
            /** Returns the number of fields available for this cursor. */
            uint fieldCount();
            /** Returns the value stored in the passed column number (counting from 0). */
            TQVariant value(uint index);
            /** Set the value for the field defined with index. The new value is buffered
            and does not got written as long as save() is not called. */
            bool setValue(uint index, TQVariant value);

            /** Save any changes done with setValue(). You should call this only once at
            the end of all value/setValue iterations cause the cursor is closed once
            the changes got saved successfully. */
            bool save();

        private:
            ::KexiDB::Cursor* m_cursor;

            class Record {
                public:
                    ::KexiDB::RowData rowdata;
                    ::KexiDB::RowEditBuffer* buffer;
                    Record(::KexiDB::Cursor* cursor)
                        : buffer( new ::KexiDB::RowEditBuffer(true) )
                    {
                        cursor->storeCurrentRow(rowdata);
                    }
                    ~Record()
                    {
                        delete buffer;
                    }
            };
            TQMap<TQ_LLONG, Record*> m_modifiedrecords;

            void clearBuffers();
    };

}}

#endif