1: <?php
2:
3: namespace RedBeanPHP;
4:
5: /**
6: * QueryWriter
7: * Interface for QueryWriters.
8: * Describes the API for a QueryWriter.
9: *
10: * Terminology:
11: *
12: * - beautified property (a camelCased property, has to be converted first)
13: * - beautified type (a camelCased type, has to be converted first)
14: * - type (a bean type, corresponds directly to a table)
15: * - property (a bean property, corresponds directly to a column)
16: * - table (a checked and quoted type, ready for use in a query)
17: * - column (a checked and quoted property, ready for use in query)
18: * - tableNoQ (same as type, but in context of a database operation)
19: * - columnNoQ (same as property, but in context of a database operation)
20: *
21: * @file RedBeanPHP/QueryWriter.php
22: * @author Gabor de Mooij and the RedBeanPHP community
23: * @license BSD/GPLv2
24: *
25: * @copyright
26: * copyright (c) G.J.G.T. (Gabor) de Mooij and the RedBeanPHP Community.
27: * This source file is subject to the BSD/GPLv2 License that is bundled
28: * with this source code in the file license.txt.
29: */
30: interface QueryWriter
31: {
32: /**
33: * SQL filter constants
34: */
35: const C_SQLFILTER_READ = 'r';
36: const C_SQLFILTER_WRITE = 'w';
37:
38: /**
39: * Query Writer constants.
40: */
41: const C_SQLSTATE_NO_SUCH_TABLE = 1;
42: const C_SQLSTATE_NO_SUCH_COLUMN = 2;
43: const C_SQLSTATE_INTEGRITY_CONSTRAINT_VIOLATION = 3;
44:
45: /**
46: * Define data type regions
47: *
48: * 00 - 80: normal data types
49: * 80 - 99: special data types, only scan/code if requested
50: * 99 : specified by user, don't change
51: */
52: const C_DATATYPE_RANGE_SPECIAL = 80;
53: const C_DATATYPE_RANGE_SPECIFIED = 99;
54:
55: /**
56: * Define GLUE types for use with glueSQLCondition methods.
57: * Determines how to prefix a snippet of SQL before appending it
58: * to other SQL (or integrating it, mixing it otherwise).
59: *
60: * WHERE - glue as WHERE condition
61: * AND - glue as AND condition
62: */
63: const C_GLUE_WHERE = 1;
64: const C_GLUE_AND = 2;
65:
66: /**
67: * Writes an SQL Snippet for a JOIN, returns the
68: * SQL snippet string.
69: *
70: * @note A default implementation is available in AQueryWriter
71: * unless a database uses very different SQL this should suffice.
72: *
73: * @param string $type source type
74: * @param string $targetType target type (type to join)
75: * @param string $leftRight type of join (possible: 'LEFT', 'RIGHT' or 'INNER').
76: *
77: * @return string $joinSQLSnippet
78: */
79: public function writeJoin( $type, $targetType, $joinType );
80:
81: /**
82: * Glues an SQL snippet to the beginning of a WHERE clause.
83: * This ensures users don't have to add WHERE to their query snippets.
84: *
85: * The snippet gets prefixed with WHERE or AND
86: * if it starts with a condition.
87: *
88: * If the snippet does NOT start with a condition (or this function thinks so)
89: * the snippet is returned as-is.
90: *
91: * The GLUE type determines the prefix:
92: *
93: * * NONE prefixes with WHERE
94: * * WHERE prefixes with WHERE and replaces AND if snippets starts with AND
95: * * AND prefixes with AND
96: *
97: * This method will never replace WHERE with AND since a snippet should never
98: * begin with WHERE in the first place. OR is not supported.
99: *
100: * Only a limited set of clauses will be recognized as non-conditions.
101: * For instance beginning a snippet with complex statements like JOIN or UNION
102: * will not work. This is too complex for use in a snippet.
103: *
104: * @note A default implementation is available in AQueryWriter
105: * unless a database uses very different SQL this should suffice.
106: *
107: * @param string $sql SQL Snippet
108: * @param integer $glue the GLUE type - how to glue (C_GLUE_WHERE or C_GLUE_AND)
109: *
110: * @return string
111: */
112: public function glueSQLCondition( $sql, $glue = NULL );
113:
114: /**
115: * Determines if there is a LIMIT 1 clause in the SQL.
116: * If not, it will add a LIMIT 1. (used for findOne).
117: *
118: * @note A default implementation is available in AQueryWriter
119: * unless a database uses very different SQL this should suffice.
120: *
121: * @param string $sql query to scan and adjust
122: *
123: * @return string
124: */
125: public function glueLimitOne( $sql );
126:
127: /**
128: * Returns the tables that are in the database.
129: *
130: * @return array
131: */
132: public function getTables();
133:
134: /**
135: * This method will create a table for the bean.
136: * This methods accepts a type and infers the corresponding table name.
137: *
138: * @param string $type type of bean you want to create a table for
139: *
140: * @return void
141: */
142: public function createTable( $type );
143:
144: /**
145: * Returns an array containing all the columns of the specified type.
146: * The format of the return array looks like this:
147: * $field => $type where $field is the name of the column and $type
148: * is a database specific description of the datatype.
149: *
150: * This methods accepts a type and infers the corresponding table name.
151: *
152: * @param string $type type of bean you want to obtain a column list of
153: *
154: * @return array
155: */
156: public function getColumns( $type );
157:
158: /**
159: * Returns the Column Type Code (integer) that corresponds
160: * to the given value type. This method is used to determine the minimum
161: * column type required to represent the given value.
162: *
163: * @param string $value value
164: *
165: * @return integer
166: */
167: public function scanType( $value, $alsoScanSpecialForTypes = FALSE );
168:
169: /**
170: * This method will add a column to a table.
171: * This methods accepts a type and infers the corresponding table name.
172: *
173: * @param string $type name of the table
174: * @param string $column name of the column
175: * @param integer $field data type for field
176: *
177: * @return void
178: */
179: public function addColumn( $type, $column, $field );
180:
181: /**
182: * Returns the Type Code for a Column Description.
183: * Given an SQL column description this method will return the corresponding
184: * code for the writer. If the include specials flag is set it will also
185: * return codes for special columns. Otherwise special columns will be identified
186: * as specified columns.
187: *
188: * @param string $typedescription description
189: * @param boolean $includeSpecials whether you want to get codes for special columns as well
190: *
191: * @return integer
192: */
193: public function code( $typedescription, $includeSpecials = FALSE );
194:
195: /**
196: * This method will widen the column to the specified data type.
197: * This methods accepts a type and infers the corresponding table name.
198: *
199: * @param string $type type / table that needs to be adjusted
200: * @param string $column column that needs to be altered
201: * @param integer $datatype target data type
202: *
203: * @return void
204: */
205: public function widenColumn( $type, $column, $datatype );
206:
207: /**
208: * Selects records from the database.
209: * This methods selects the records from the database that match the specified
210: * type, conditions (optional) and additional SQL snippet (optional).
211: *
212: * @param string $type name of the table you want to query
213: * @param array $conditions criteria ( $column => array( $values ) )
214: * @param string $addSQL additional SQL snippet
215: * @param array $bindings bindings for SQL snippet
216: *
217: * @return array
218: */
219: public function queryRecord( $type, $conditions = array(), $addSql = NULL, $bindings = array() );
220:
221: /**
222: * Selects records from the database and returns a cursor.
223: * This methods selects the records from the database that match the specified
224: * type, conditions (optional) and additional SQL snippet (optional).
225: *
226: * @param string $type name of the table you want to query
227: * @param array $conditions criteria ( $column => array( $values ) )
228: * @param string $addSQL additional SQL snippet
229: * @param array $bindings bindings for SQL snippet
230: *
231: * @return Cursor
232: */
233: public function queryRecordWithCursor( $type, $addSql = NULL, $bindings = array() );
234:
235: /**
236: * Returns records through an intermediate type. This method is used to obtain records using a link table and
237: * allows the SQL snippets to reference columns in the link table for additional filtering or ordering.
238: *
239: * @param string $sourceType source type, the reference type you want to use to fetch related items on the other side
240: * @param string $destType destination type, the target type you want to get beans of
241: * @param mixed $linkID ID to use for the link table
242: * @param string $addSql Additional SQL snippet
243: * @param array $bindings Bindings for SQL snippet
244: *
245: * @return array
246: */
247: public function queryRecordRelated( $sourceType, $destType, $linkID, $addSql = '', $bindings = array() );
248:
249: /**
250: * Returns the row that links $sourceType $sourcID to $destType $destID in an N-M relation.
251: *
252: * @param string $sourceType source type, the first part of the link you're looking for
253: * @param string $destType destination type, the second part of the link you're looking for
254: * @param string $sourceID ID for the source
255: * @param string $destID ID for the destination
256: *
257: * @return array|null
258: */
259: public function queryRecordLink( $sourceType, $destType, $sourceID, $destID );
260:
261: /**
262: * Counts the number of records in the database that match the
263: * conditions and additional SQL.
264: *
265: * @param string $type name of the table you want to query
266: * @param array $conditions criteria ( $column => array( $values ) )
267: * @param string $addSQL additional SQL snippet
268: * @param array $bindings bindings for SQL snippet
269: *
270: * @return integer
271: */
272: public function queryRecordCount( $type, $conditions = array(), $addSql = NULL, $bindings = array() );
273:
274: /**
275: * Returns the number of records linked through $linkType and satisfying the SQL in $addSQL/$bindings.
276: *
277: * @param string $sourceType source type
278: * @param string $targetType the thing you want to count
279: * @param mixed $linkID the of the source type
280: * @param string $addSQL additional SQL snippet
281: * @param array $bindings bindings for SQL snippet
282: *
283: * @return integer
284: */
285: public function queryRecordCountRelated( $sourceType, $targetType, $linkID, $addSQL = '', $bindings = array() );
286:
287: /**
288: * Returns all rows of specified type that have been tagged with one of the
289: * strings in the specified tag list array.
290: *
291: * Note that the additional SQL snippet can only be used for pagination,
292: * the SQL snippet will be appended to the end of the query.
293: *
294: * @param string $type the bean type you want to query
295: * @param array $tagList an array of strings, each string containing a tag title
296: * @param boolean $all if TRUE only return records that have been associated with ALL the tags in the list
297: * @param string $addSql addition SQL snippet, for pagination
298: * @param array $bindings parameter bindings for additional SQL snippet
299: *
300: * @return array
301: */
302: public function queryTagged( $type, $tagList, $all = FALSE, $addSql = '', $bindings = array() );
303:
304: /**
305: * This method should update (or insert a record), it takes
306: * a table name, a list of update values ( $field => $value ) and an
307: * primary key ID (optional). If no primary key ID is provided, an
308: * INSERT will take place.
309: * Returns the new ID.
310: * This methods accepts a type and infers the corresponding table name.
311: *
312: * @param string $type name of the table to update
313: * @param array $updatevalues list of update values
314: * @param integer $id optional primary key ID value
315: *
316: * @return integer
317: */
318: public function updateRecord( $type, $updatevalues, $id = NULL );
319:
320: /**
321: * Deletes records from the database.
322: * @note $addSql is always prefixed with ' WHERE ' or ' AND .'
323: *
324: * @param string $type name of the table you want to query
325: * @param array $conditions criteria ( $column => array( $values ) )
326: * @param string $sql additional SQL
327: * @param array $bindings bindings
328: *
329: * @return void
330: */
331: public function deleteRecord( $type, $conditions = array(), $addSql = '', $bindings = array() );
332:
333: /**
334: * Deletes all links between $sourceType and $destType in an N-M relation.
335: *
336: * @param string $sourceType source type
337: * @param string $destType destination type
338: * @param string $sourceID source ID
339: *
340: * @return void
341: */
342: public function deleteRelations( $sourceType, $destType, $sourceID );
343:
344: /**
345: * @see QueryWriter::addUniqueConstaint
346: */
347: public function addUniqueIndex( $type, $columns );
348:
349: /**
350: * This method will add a UNIQUE constraint index to a table on columns $columns.
351: * This methods accepts a type and infers the corresponding table name.
352: *
353: * @param string $type target bean type
354: * @param array $columnsPartOfIndex columns to include in index
355: *
356: * @return void
357: */
358: public function addUniqueConstraint( $type, $columns );
359:
360: /**
361: * This method will check whether the SQL state is in the list of specified states
362: * and returns TRUE if it does appear in this list or FALSE if it
363: * does not. The purpose of this method is to translate the database specific state to
364: * a one of the constants defined in this class and then check whether it is in the list
365: * of standard states provided.
366: *
367: * @param string $state SQL state to consider
368: * @param array $list list of standardized SQL state constants to check against
369: *
370: * @return boolean
371: */
372: public function sqlStateIn( $state, $list );
373:
374: /**
375: * This method will remove all beans of a certain type.
376: * This methods accepts a type and infers the corresponding table name.
377: *
378: * @param string $type bean type
379: *
380: * @return void
381: */
382: public function wipe( $type );
383:
384: /**
385: * This method will add a foreign key from type and field to
386: * target type and target field.
387: * The foreign key is created without an action. On delete/update
388: * no action will be triggered. The FK is only used to allow database
389: * tools to generate pretty diagrams and to make it easy to add actions
390: * later on.
391: * This methods accepts a type and infers the corresponding table name.
392: *
393: *
394: * @param string $type type that will have a foreign key field
395: * @param string $targetType points to this type
396: * @param string $property field that contains the foreign key value
397: * @param string $targetProperty field where the fk points to
398: * @param string $isDep whether target is dependent and should cascade on update/delete
399: *
400: * @return void
401: */
402: public function addFK( $type, $targetType, $property, $targetProperty, $isDep = false );
403:
404: /**
405: * This method will add an index to a type and field with name
406: * $name.
407: * This methods accepts a type and infers the corresponding table name.
408: *
409: * @param string $type type to add index to
410: * @param string $name name of the new index
411: * @param string $property field to index
412: *
413: * @return void
414: */
415: public function addIndex( $type, $name, $property );
416:
417: /**
418: * Checks and filters a database structure element like a table of column
419: * for safe use in a query. A database structure has to conform to the
420: * RedBeanPHP DB security policy which basically means only alphanumeric
421: * symbols are allowed. This security policy is more strict than conventional
422: * SQL policies and does therefore not require database specific escaping rules.
423: *
424: * @param string $databaseStructure name of the column/table to check
425: * @param boolean $noQuotes TRUE to NOT put backticks or quotes around the string
426: *
427: * @return string
428: */
429: public function esc( $databaseStructure, $dontQuote = FALSE );
430:
431: /**
432: * Removes all tables and views from the database.
433: *
434: * @return void
435: */
436: public function wipeAll();
437:
438: /**
439: * Renames an association. For instance if you would like to refer to
440: * album_song as: track you can specify this by calling this method like:
441: *
442: * <code>
443: * renameAssociation('album_song','track')
444: * </code>
445: *
446: * This allows:
447: *
448: * <code>
449: * $album->sharedSong
450: * </code>
451: *
452: * to add/retrieve beans from track instead of album_song.
453: * Also works for exportAll().
454: *
455: * This method also accepts a single associative array as
456: * its first argument.
457: *
458: * @param string|array $fromType original type name, or array
459: * @param string $toType new type name (only if 1st argument is string)
460: *
461: * @return void
462: */
463: public function renameAssocTable( $fromType, $toType = NULL );
464:
465: /**
466: * Returns the format for link tables.
467: * Given an array containing two type names this method returns the
468: * name of the link table to be used to store and retrieve
469: * association records. For instance, given two types: person and
470: * project, the corresponding link table might be: 'person_project'.
471: *
472: * @param array $types two types array($type1, $type2)
473: *
474: * @return string
475: */
476: public function getAssocTable( $types );
477:
478: /**
479: * Given a bean type and a property, this method
480: * tries to infer the fetch type using the foreign key
481: * definitions in the database.
482: * For instance: project, student -> person.
483: * If no fetchType can be inferred, this method will return NULL.
484: *
485: * @note QueryWriters do not have to implement this method,
486: * it's optional. A default version is available in AQueryWriter.
487: *
488: * @param $type the source type to fetch a target type for
489: * @param $property the property to fetch the type of
490: *
491: * @return string|NULL
492: */
493: public function inferFetchType( $type, $property );
494: }
495: