KDb

KDbConnectionProxy.h
1/* This file is part of the KDE project
2 Copyright (C) 2016 Jarosław Staniek <staniek@kde.org>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18*/
19
20#ifndef KDB_CONNECTIONPROXY_H
21#define KDB_CONNECTIONPROXY_H
22
23#include <KDbConnection>
24
25//! The KDbConnectionProxy class gives access to protected (low-level) API of KDbConnection
26/**
27 * The connection object specified in constructor of the proxy is called a parent connection.
28 * All inherited methods of the KDbConnection API call equivalent methods of the parent
29 * connection. The KDbConnectionProxy class also provides non-virtual methods that are
30 * equivalent to KDbConnection ones. These KDbConnection's equivalent methods are called
31 * by the proxy too.
32 *
33 * Example use of this class is Kexi's database database migration plugins when the source
34 * database is only accessibly using low-level routines.
35 */
36class KDB_EXPORT KDbConnectionProxy : protected KDbConnection
37{
38public:
39 //! Creates a proxy object for parent @a connection.
40 //! @a connection must not be @c nullptr.
41 //! It is owned by this proxy unless setConnectionIsOwned(false) is called.
42 explicit KDbConnectionProxy(KDbConnection *connection);
43
44 //! Deletes this proxy. Owned connection is closed and destroyed.
45 ~KDbConnectionProxy() override;
46
47 //! @return parent connection for this proxy
49
50 //! @overload KDbConnection *parentConnection()
51 const KDbConnection *parentConnection() const;
52
53 //! Control owhership of parent connection that is assigned to this proxy.
54 //! Owned connection is closed and destroyed upon destruction of the KDbConnectionProxy
55 //! object.
56 void setParentConnectionIsOwned(bool set);
57
58 KDbConnectionData data() const;
59
60 KDbDriver* driver() const;
61
62 bool connect();
63
64 bool isConnected() const;
65
66 bool isDatabaseUsed() const;
67
69
70 void clearResult();
71
72 KDbResult result() const;
73
74 KDbResultable resultable() const;
75
76 bool disconnect();
77
78 QStringList databaseNames(bool also_system_db = false);
79
80 bool databaseExists(const QString &dbName, bool ignoreErrors = true);
81
82 bool createDatabase(const QString &dbName);
83
84 bool useDatabase(const QString &dbName = QString(), bool kexiCompatible = true, bool *cancelled = nullptr,
85 KDbMessageHandler* msgHandler = nullptr);
86
87 bool closeDatabase();
88
90
91 bool dropDatabase(const QString &dbName = QString());
92
93 QStringList objectNames(int objectType = KDb::AnyObjectType, bool* ok = nullptr);
94
95 QStringList tableNames(bool alsoSystemTables = false, bool* ok = nullptr);
96
97 tristate containsTable(const QString &tableName);
98
100
102
104
105 QList<int> tableIds(bool* ok = nullptr);
106
107 QList<int> queryIds(bool* ok = nullptr);
108
109 QList<int> objectIds(int objectType, bool* ok = nullptr);
110
112
114 KDbTransaction::CommitOptions options = KDbTransaction::CommitOptions());
115
117 KDbTransaction::CommitOptions options = KDbTransaction::CommitOptions());
118
120
121 void setDefaultTransaction(const KDbTransaction& trans);
122
124
125 bool autoCommit() const;
126
127 bool setAutoCommit(bool on);
128
129 KDbEscapedString escapeString(const QString& str) const override;
130
131 KDbCursor *prepareQuery(const KDbEscapedString &sql,
132 KDbCursor::Options options = KDbCursor::Option::None) override;
133
134 KDbCursor *prepareQuery(KDbQuerySchema *query,
135 KDbCursor::Options options = KDbCursor::Option::None) override;
136
137 KDbCursor *prepareQuery(KDbTableSchema *table,
138 KDbCursor::Options options = KDbCursor::Option::None);
139
140 KDbCursor *executeQuery(const KDbEscapedString &sql,
141 KDbCursor::Options options = KDbCursor::Option::None);
142
143 KDbCursor* executeQuery(KDbQuerySchema* query, const QList<QVariant>& params,
144 KDbCursor::Options options = KDbCursor::Option::None);
145
146 KDbCursor* executeQuery(KDbQuerySchema* query, KDbCursor::Options options = KDbCursor::Option::None);
147
148 KDbCursor* executeQuery(KDbTableSchema* table, KDbCursor::Options options = KDbCursor::Option::None);
149
150 bool deleteCursor(KDbCursor *cursor);
151
152 KDbTableSchema* tableSchema(int tableId);
153
154 KDbTableSchema* tableSchema(const QString& tableName);
155
156 KDbQuerySchema* querySchema(int queryId);
157
158 KDbQuerySchema* querySchema(const QString& queryName);
159
160 bool setQuerySchemaObsolete(const QString& queryName);
161
163 QueryRecordOptions options = QueryRecordOption::Default);
164
165 tristate querySingleRecord(KDbQuerySchema* query, KDbRecordData* data,
166 QueryRecordOptions options = QueryRecordOption::Default);
167
168 tristate querySingleRecord(KDbQuerySchema* query, KDbRecordData* data,
169 const QList<QVariant>& params,
170 QueryRecordOptions options = QueryRecordOption::Default);
171
172 tristate querySingleString(const KDbEscapedString& sql, QString* value, int column = 0,
173 QueryRecordOptions options = QueryRecordOption::Default);
174
175 tristate querySingleString(KDbQuerySchema* query, QString* value, int column = 0,
176 QueryRecordOptions options = QueryRecordOption::Default);
177
178 tristate querySingleString(KDbQuerySchema* query, QString* value,
179 const QList<QVariant>& params, int column = 0,
180 QueryRecordOptions options = QueryRecordOption::Default);
181
182 tristate querySingleNumber(const KDbEscapedString& sql, int* number, int column = 0,
183 QueryRecordOptions options = QueryRecordOption::Default);
184
185 tristate querySingleNumber(KDbQuerySchema* query, int* number, int column = 0,
186 QueryRecordOptions options = QueryRecordOption::Default);
187
188 tristate querySingleNumber(KDbQuerySchema* query, int* number,
189 const QList<QVariant>& params, int column = 0,
190 QueryRecordOptions options = QueryRecordOption::Default);
191
192 bool queryStringList(const KDbEscapedString& sql, QStringList* list, int column = 0);
193
194 bool queryStringList(KDbQuerySchema* query, QStringList* list, int column = 0);
195
196 bool queryStringList(KDbQuerySchema* query, QStringList* list,
197 const QList<QVariant>& params, int column = 0);
198
199 tristate resultExists(const KDbEscapedString &sql, QueryRecordOptions options
200 = QueryRecordOption::Default);
201
203
204 KDbEscapedString recentSqlString() const override;
205
206 //PROTOTYPE:
207#define A , const QVariant&
208#define H_INS_REC(args) bool insertRecord(KDbTableSchema* tableSchema args)
209#define H_INS_REC_ALL \
210 H_INS_REC(A); \
211 H_INS_REC(A A); \
212 H_INS_REC(A A A); \
213 H_INS_REC(A A A A); \
214 H_INS_REC(A A A A A); \
215 H_INS_REC(A A A A A A); \
216 H_INS_REC(A A A A A A A); \
217 H_INS_REC(A A A A A A A A)
218 H_INS_REC_ALL;
219
220#undef H_INS_REC
221#define H_INS_REC(args) bool insertRecord(KDbFieldList* fields args)
222
223 H_INS_REC_ALL;
224#undef H_INS_REC_ALL
225#undef H_INS_REC
226#undef A
227
228 bool insertRecord(KDbTableSchema* tableSchema, const QList<QVariant>& values);
229
230 bool insertRecord(KDbFieldList* fields, const QList<QVariant>& values);
231
232 bool createTable(KDbTableSchema *tableSchema,
233 CreateTableOptions options = CreateTableOption::Default);
234
235 KDbTableSchema *copyTable(const KDbTableSchema &tableSchema, const KDbObject &newData);
236
237 KDbTableSchema *copyTable(const QString& tableName, const KDbObject &newData);
238
239 tristate dropTable(KDbTableSchema* tableSchema);
240
241 tristate dropTable(const QString& tableName);
242
243 tristate alterTable(KDbTableSchema* tableSchema, KDbTableSchema* newTableSchema);
244
245 bool alterTableName(KDbTableSchema* tableSchema, const QString& newName,
246 AlterTableNameOptions options = AlterTableNameOption::Default);
247
248 bool dropQuery(KDbQuerySchema* querySchema);
249
250 bool dropQuery(const QString& queryName);
251
252 bool removeObject(int objId);
253
254 KDbField* findSystemFieldName(const KDbFieldList& fieldlist);
255
257
258 void setAvailableDatabaseName(const QString& dbName);
259
261
262 Q_REQUIRED_RESULT QSharedPointer<KDbSqlResult> prepareSql(const KDbEscapedString& sql);
263
264 bool executeSql(const KDbEscapedString& sql);
265
266 bool storeObjectData(KDbObject* object);
267
268 bool storeNewObjectData(KDbObject* object);
269
270 //! @since 3.1
271 tristate loadObjectData(int type, int id, KDbObject* object);
272
273 tristate loadObjectData(int type, const QString& name, KDbObject* object);
274
275 tristate loadDataBlock(int objectID, QString* dataString, const QString& dataID = QString());
276
277 bool storeDataBlock(int objectID, const QString &dataString,
278 const QString& dataID = QString());
279
280 bool copyDataBlock(int sourceObjectID, int destObjectID, const QString& dataID = QString());
281
282 bool removeDataBlock(int objectID, const QString& dataID = QString());
283
285 KDbFieldList* fields, const QStringList& whereFieldNames = QStringList());
286
287 bool isInternalTableSchema(const QString& tableName);
288
289 QString escapeIdentifier(const QString& id) const override;
290
291 bool drv_connect() override;
292
293 bool drv_disconnect() override;
294
295 bool drv_getServerVersion(KDbServerVersionInfo* version) override;
296
297 /**
298 * @since 3.2
299 */
300 QStringList drv_getTableNames(bool *ok) override;
301
302 tristate drv_containsTable(const QString &tableName) override;
303
304 bool drv_createTable(const KDbTableSchema& tableSchema) override;
305
306 bool drv_alterTableName(KDbTableSchema* tableSchema, const QString& newName) override;
307
308 bool drv_copyTableData(const KDbTableSchema &tableSchema,
309 const KDbTableSchema &destinationTableSchema) override;
310
311 bool drv_dropTable(const QString& tableName) override;
312
313 tristate dropTableInternal(KDbTableSchema* tableSchema, bool alsoRemoveSchema);
314
315 bool setupObjectData(const KDbRecordData& data, KDbObject* object);
316
317 KDbField* setupField(const KDbRecordData& data);
318
319 Q_REQUIRED_RESULT KDbSqlResult *drv_prepareSql(const KDbEscapedString &sql) override;
320
321 bool drv_executeSql(const KDbEscapedString& sql) override;
322
323 bool drv_getDatabasesList(QStringList* list) override;
324
325 bool drv_databaseExists(const QString &dbName, bool ignoreErrors = true) override;
326
327 bool drv_createDatabase(const QString &dbName = QString()) override;
328
329 bool drv_useDatabase(const QString &dbName = QString(), bool *cancelled = nullptr,
330 KDbMessageHandler* msgHandler = nullptr) override;
331
332 bool drv_closeDatabase() override;
333
334 bool drv_isDatabaseUsed() const override;
335
336 bool drv_dropDatabase(const QString &dbName = QString()) override;
337
338 bool drv_createTable(const QString& tableName) override;
339
341
342 bool drv_commitTransaction(KDbTransactionData* trans) override;
343
344 bool drv_rollbackTransaction(KDbTransactionData* trans) override;
345
346 bool drv_beforeInsert(const QString& tableName, KDbFieldList* fields) override;
347
348 bool drv_afterInsert(const QString& tableName, KDbFieldList* fields) override;
349
350 bool drv_beforeUpdate(const QString& tableName, KDbFieldList* fields) override;
351
352 bool drv_afterUpdate(const QString& tableName, KDbFieldList* fields) override;
353
354 bool drv_setAutoCommit(bool on) override;
355
357
359
361
363
364 bool checkConnected();
365
366 bool checkIsDatabaseUsed();
367
368 bool updateRecord(KDbQuerySchema* query, KDbRecordData* data, KDbRecordEditBuffer* buf, bool useRecordId = false);
369
370 bool insertRecord(KDbQuerySchema* query, KDbRecordData* data, KDbRecordEditBuffer* buf, bool getRecordId = false);
371
372 bool deleteRecord(KDbQuerySchema* query, KDbRecordData* data, bool useRecordId = false);
373
374 bool deleteAllRecords(KDbQuerySchema* query);
375
376 bool checkIfColumnExists(KDbCursor *cursor, int column);
377
379 KDbQuerySchema* query, const QList<QVariant>* params,
380 QueryRecordOptions options);
381
383 KDbQuerySchema* query, const QList<QVariant>* params,
384 int column, QueryRecordOptions options);
385
387 KDbQuerySchema* query, const QList<QVariant>* params,
388 int column, QueryRecordOptions options);
389
391 KDbQuerySchema* query, const QList<QVariant>* params,
392 int column, bool (*filterFunction)(const QString&));
393
394 KDbCursor* executeQueryInternal(const KDbEscapedString& sql, KDbQuerySchema* query,
395 const QList<QVariant>* params);
396
398
400
401 bool storeMainFieldSchema(KDbField *field);
402
403private:
404 Q_DISABLE_COPY(KDbConnectionProxy)
405 class Private;
406 Private * const d;
407};
408
409#endif
Database specific connection data, e.g. host, port.
Generic options for a single connection. The options are accessible using key/value pairs....
void setParentConnectionIsOwned(bool set)
Control owhership of parent connection that is assigned to this proxy.
KDbConnection * parentConnection()
KDbConnectionProxy(KDbConnection *connection)
Creates a proxy object for parent connection.
bool connect()
Connects to driver with given parameters.
virtual QStringList drv_getTableNames(bool *ok)
LOW LEVEL METHOD.
bool updateRecord(KDbQuerySchema *query, KDbRecordData *data, KDbRecordEditBuffer *buf, bool useRecordId=false)
virtual KDbEscapedString escapeString(const QString &str) const
bool removeObject(int objId)
tristate loadObjectData(int type, int id, KDbObject *object)
tristate loadDataBlock(int objectID, QString *dataString, const QString &dataID=QString())
KDbField * setupField(const KDbRecordData &data)
virtual bool drv_setAutoCommit(bool on)
KDbTableSchema * copyTable(const KDbTableSchema &tableSchema, const KDbObject &newData)
bool databaseExists(const QString &dbName, bool ignoreErrors=true)
bool queryStringList(const KDbEscapedString &sql, QStringList *list, int column=0)
bool removeDataBlock(int objectID, const QString &dataID=QString())
virtual bool drv_closeDatabase()=0
virtual KDbPreparedStatementInterface * prepareStatementInternal()=0
bool storeMainFieldSchema(KDbField *field)
void setAvailableDatabaseName(const QString &dbName)
bool setQuerySchemaObsolete(const QString &queryName)
QList< int > tableIds(bool *ok=nullptr)
KDbProperties databaseProperties() const
KDbPreparedStatement prepareStatement(KDbPreparedStatement::Type type, KDbFieldList *fields, const QStringList &whereFieldNames=QStringList())
bool commitAutoCommitTransaction(const KDbTransaction &trans)
tristate querySingleString(const KDbEscapedString &sql, QString *value, int column=0, QueryRecordOptions options=QueryRecordOption::Default)
virtual bool drv_getServerVersion(KDbServerVersionInfo *version)=0
KDbCursor * executeQuery(const KDbEscapedString &sql, KDbCursor::Options options=KDbCursor::Option::None)
virtual bool drv_alterTableName(KDbTableSchema *tableSchema, const QString &newName)
bool closeDatabase()
Closes currently used database for this connection.
virtual bool drv_isDatabaseUsed() const
virtual bool drv_executeSql(const KDbEscapedString &sql)=0
Executes query for a raw SQL statement sql without returning resulting records.
virtual bool drv_useDatabase(const QString &dbName=QString(), bool *cancelled=nullptr, KDbMessageHandler *msgHandler=nullptr)=0
void setDefaultTransaction(const KDbTransaction &trans)
Sets default transaction.
QStringList tableNames(bool alsoSystemTables=false, bool *ok=nullptr)
bool executeSql(const KDbEscapedString &sql)
Executes a new native (raw, backend-specific) SQL query.
friend class KDbProperties
for setError()
bool autoCommit() const
virtual KDbSqlResult * drv_prepareSql(const KDbEscapedString &sql)=0
Prepares query for a raw SQL statement sql with possibility of returning records.
tristate querySingleStringInternal(const KDbEscapedString *sql, QString *value, KDbQuerySchema *query, const QList< QVariant > *params, int column, QueryRecordOptions options)
virtual bool drv_disconnect()=0
virtual QString escapeIdentifier(const QString &id) const
Identifier escaping function in the associated KDbDriver.
virtual bool drv_createDatabase(const QString &dbName=QString())=0
bool storeDataBlock(int objectID, const QString &dataString, const QString &dataID=QString())
KDbConnectionData data() const
tristate dropTable(KDbTableSchema *tableSchema)
virtual QString anyAvailableDatabaseName()
virtual KDbTransactionData * drv_beginTransaction()
KDbServerVersionInfo serverVersion() const
virtual bool drv_createTable(const KDbTableSchema &tableSchema)
Creates table using tableSchema information.
tristate alterTable(KDbTableSchema *tableSchema, KDbTableSchema *newTableSchema)
virtual bool drv_databaseExists(const QString &dbName, bool ignoreErrors=true)
tristate isEmpty(KDbTableSchema *table)
virtual bool drv_copyTableData(const KDbTableSchema &tableSchema, const KDbTableSchema &destinationTableSchema)
KDbField * findSystemFieldName(const KDbFieldList &fieldlist)
bool isConnected() const
bool dropDatabase(const QString &dbName=QString())
Drops database with name dbName.
QStringList databaseNames(bool also_system_db=false)
virtual KDbCursor * prepareQuery(const KDbEscapedString &sql, KDbCursor::Options options=KDbCursor::Option::None)=0
bool deleteCursor(KDbCursor *cursor)
bool checkIfColumnExists(KDbCursor *cursor, int column)
bool rollbackTransaction(KDbTransaction trans=KDbTransaction(), KDbTransaction::CommitOptions options=KDbTransaction::CommitOptions())
Rolls back specified transaction for this connection.
virtual bool drv_dropDatabase(const QString &dbName=QString())=0
bool createTable(KDbTableSchema *tableSchema, CreateTableOptions options=CreateTableOption::Default)
Creates a new table.
virtual bool drv_rollbackTransaction(KDbTransactionData *trans)
KDbTransaction beginTransaction()
Starts a new database transaction.
bool loadExtendedTableSchemaData(KDbTableSchema *tableSchema)
bool deleteAllRecords(KDbQuerySchema *query)
QStringList objectNames(int objectType=KDb::AnyObjectType, bool *ok=nullptr)
QSharedPointer< KDbSqlResult > prepareSql(const KDbEscapedString &sql)
Prepares execution of a new native (raw, backend-specific) SQL query.
virtual bool drv_dropTable(const QString &tableName)
QList< int > objectIds(int objectType, bool *ok=nullptr)
bool disconnect()
Disconnects from driver with given parameters.
bool checkIsDatabaseUsed()
tristate querySingleRecordInternal(KDbRecordData *data, const KDbEscapedString *sql, KDbQuerySchema *query, const QList< QVariant > *params, QueryRecordOptions options)
KDbDriver * driver() const
bool storeObjectData(KDbObject *object)
tristate querySingleRecord(const KDbEscapedString &sql, KDbRecordData *data, QueryRecordOptions options=QueryRecordOption::Default)
KDbTableSchema * tableSchema(int tableId)
friend class KDbTableSchema
for removeMe()
bool storeExtendedTableSchemaData(KDbTableSchema *tableSchema)
KDbCursor * executeQueryInternal(const KDbEscapedString &sql, KDbQuerySchema *query, const QList< QVariant > *params)
bool dropQuery(KDbQuerySchema *querySchema)
bool isDatabaseUsed() const
virtual bool drv_connect()=0
bool copyDataBlock(int sourceObjectID, int destObjectID, const QString &dataID=QString())
tristate querySingleNumber(const KDbEscapedString &sql, int *number, int column=0, QueryRecordOptions options=QueryRecordOption::Default)
bool createDatabase(const QString &dbName)
Creates new database with name dbName, using this connection.
QString currentDatabase() const
Get the name of the current database.
bool useDatabase(const QString &dbName=QString(), bool kexiCompatible=true, bool *cancelled=nullptr, KDbMessageHandler *msgHandler=nullptr)
Opens an existing database specified by dbName.
virtual bool drv_beforeInsert(const QString &tableName, KDbFieldList *fields)
virtual bool drv_afterInsert(const QString &tableName, KDbFieldList *fields)
bool setupObjectData(const KDbRecordData &data, KDbObject *object)
virtual KDbEscapedString recentSqlString() const
Return recently used SQL string.
bool beginAutoCommitTransaction(KDbTransactionGuard *tg)
KDbVersionInfo databaseVersion() const
QList< int > queryIds(bool *ok=nullptr)
bool alterTableName(KDbTableSchema *tableSchema, const QString &newName, AlterTableNameOptions options=AlterTableNameOption::Default)
Alters name of table.
bool rollbackAutoCommitTransaction(const KDbTransaction &trans)
tristate resultExists(const KDbEscapedString &sql, QueryRecordOptions options=QueryRecordOption::Default)
virtual bool drv_afterUpdate(const QString &tableName, KDbFieldList *fields)
bool deleteRecord(KDbQuerySchema *query, KDbRecordData *data, bool useRecordId=false)
QList< KDbTransaction > transactions()
Returns set of handles of currently active transactions.
KDbConnection(KDbDriver *driver, const KDbConnectionData &connData, const KDbConnectionOptions &options)
tristate dropTableInternal(KDbTableSchema *tableSchema, bool alsoRemoveSchema)
bool useTemporaryDatabaseIfNeeded(QString *name)
virtual bool drv_beforeUpdate(const QString &tableName, KDbFieldList *fields)
KDbQuerySchema * querySchema(int queryId)
bool storeNewObjectData(KDbObject *object)
bool setAutoCommit(bool on)
bool commitTransaction(KDbTransaction transaction=KDbTransaction(), KDbTransaction::CommitOptions options=KDbTransaction::CommitOptions())
Commits specified transaction for this connection.
virtual bool drv_commitTransaction(KDbTransactionData *trans)
KDbTransaction defaultTransaction() const
Returns handle of default transaction for this connection.
virtual tristate drv_containsTable(const QString &tableName)=0
virtual bool drv_getDatabasesList(QStringList *list)
tristate querySingleNumberInternal(const KDbEscapedString *sql, int *number, KDbQuerySchema *query, const QList< QVariant > *params, int column, QueryRecordOptions options)
tristate containsTable(const QString &tableName)
KDbConnectionOptions * options()
bool queryStringListInternal(const KDbEscapedString *sql, QStringList *list, KDbQuerySchema *query, const QList< QVariant > *params, int column, bool(*filterFunction)(const QString &))
Specialized string for escaping.
Meta-data for a field.
Definition KDbField.h:72
Prepared statement interface for backend-dependent implementations.
Prepared database command for optimizing sequences of multiple database actions.
Type
Defines type of the prepared statement.
Structure for storing single record with type information.
provides data for single edited database record
The KDbSqlResult class abstracts result of a raw SQL query preparation by KDbConnection::prepareSql()
Internal prototype for storing transaction handle for KDbTransaction object.
KDbTransactionGuard class is a convenience class that simplifies handling transactions.
This class encapsulates a single database transaction.
3-state logical type with three values: true, false and cancelled and convenient operators.
@ AnyObjectType
helper
Definition KDbGlobal.h:132
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Feb 21 2025 11:51:49 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.