Framework  3.9
AbstractJoin Class Reference

AbstractJoin is the abstract base class from which concrete join classes can be derived in order to provide support for different styles of relational join. More...

+ Inheritance diagram for AbstractJoin:

Public Member Functions

 add ($class)
 Adds a class to the join definition. More...
 
 setFilter ($class, $filter)
 Sets an InclusionFilter or ExclusionFilter on the specified class. More...
 
 constrain ($class, $constraint)
 Sets a query constraint on the given class. More...
 
 excludeKeyFromJoin ($class, $key)
 By default joins are generated following the "most restrictive search" principle. More...
 
 xref ($xref, $xrefFieldMaps=null)
 Adds a cross-reference class to the join definition. More...
 
 pseudo ($class, $items, $indexField)
 Registers a class and indexed array as a pseudo-join item. More...
 
 generateQuery ($constraint="", $count=false)
 
 count ($constraints="", $countExpr=true)
 
 query ($constraints="", $page=-1, $size=-1)
 Performs a query against the database returning an array of JoinResult objects. More...
 
 iteratedQuery ($constraints="")
 Performs a query against the database returning an iterator of JoinResult objects. More...
 
 indexedQuery ($constraints="", $indexBy="")
 Performs a query against the database, returning an array of DataItem objects of the specified class, indexed by a particular field. More...
 
 groupedQuery ($constraints="", $indexBy="")
 Performs a query against the database, returning an array of arrays of DataItem objects of the specified class, grouped by a particular field. More...
 

Public Attributes

 $classes = array()
 The names of the DataItem classes being joined. More...
 
 $protos = array()
 Prototype instances of the DataItem classes being joined. More...
 
 $xrefs = array()
 Cross-reference classes (i.e. classes that are part of the join, but not the result) More...
 
 $xrefFieldMaps = array()
 Cross-reference field map (to support cross-referencing through fields with differing names) More...
 
 $aliases = array()
 Field aliases for output. More...
 
 $xrefAliases = array()
 Cross-reference table aliases. More...
 
 $constraints = array()
 Class-specific constraints add via the constrain() method. More...
 
 $unique = false
 true to output distinct rows only More...
 
 $tag = "join"
 XML tag name. More...
 
 $excludedKeys = array()
 
 $pseudos = array()
 Pseudo-join lookup tables. More...
 

Detailed Description

AbstractJoin is the abstract base class from which concrete join classes can be derived in order to provide support for different styles of relational join.

Author
andy

Definition at line 232 of file join.inc.

Member Function Documentation

◆ add()

AbstractJoin::add (   $class)

Adds a class to the join definition.

Classes added using this method are included in the eventual result set.

Parameters
string$classthe name of the class to add to the join
Filter$filter(optional) InclusionFilter or ExclusionFilter object defining the sub-set of fields to include

Definition at line 256 of file join.inc.

257  {
258  $this->classes[] = $class;
259 
260  $this->protos[$class] = new $class;
261 
262  if (func_num_args() > 1)
263  {
264  $filter = new InclusionFilter();
265 
266  if (func_get_arg(1) !== false)
267  {
268  for($i = 1; $i < func_num_args(); ++$i)
269  {
270  $filter->add(func_get_arg($i));
271  }
272  }
273 
274  $this->protos[$class]->filter = $filter;
275  }
276 
277  return $this;
278  }
Used to place a filter on the contents of a DataItem-derived object.

◆ constrain()

AbstractJoin::constrain (   $class,
  $constraint 
)

Sets a query constraint on the given class.

Parameters
string$classthe class to be constrained
string$constraintthe SQL constraint to be applied

Definition at line 296 of file join.inc.

297  {
298  $this->constraints[$class] = $constraint;
299  }

◆ count()

AbstractJoin::count (   $constraints = "",
  $countExpr = true 
)

Definition at line 356 of file join.inc.

357  {
358  $query = $this->generateQuery($constraints, $countExpr);
359  try
360  {
362 
363  $result = $db->prepare($query);
364  $result->execute($this->params);
365 
366  if ($row = $result->fetch())
367  {
368  $value = $row['result'];
369  }
370 
371  unset($result);
372  }
373  catch(PDOException $e)
374  {
375  throw FakoliException($e->getMessage());
376  }
377 
378  return $value;
379  }
$constraints
Class-specific constraints add via the constrain() method.
Definition: join.inc:242
generateQuery($constraint="", $count=false)
static getConnection()
Retrieves a reference to the global database connection.

◆ excludeKeyFromJoin()

AbstractJoin::excludeKeyFromJoin (   $class,
  $key 
)

By default joins are generated following the "most restrictive search" principle.

This means that all matching foreign key/primary key pairs are used in the join constraint. You can use this method to override this behavior for a member of the join, specifying that a given key should not be used as part of the join constraint.

Parameters
string$class
string$key

Definition at line 311 of file join.inc.

312  {
313  if (!isset($this->excludedKeys[$class]))
314  {
315  $this->excludedKeys[$class] = array();
316  }
317 
318  $this->excludedKeys[$class][$key] = true;
319 
320  trace("*** Excluding $key on $class", 3);
321  return $this;
322  }
trace($msg, $lvl=3, $callStack=null)
Send output to the trace log.
Definition: functions.inc:1010

◆ generateQuery()

AbstractJoin::generateQuery (   $constraint = "",
  $count = false 
)
abstract

Reimplemented in LeftOuterJoin, and InnerJoin.

◆ groupedQuery()

AbstractJoin::groupedQuery (   $constraints = "",
  $indexBy = "" 
)

Performs a query against the database, returning an array of arrays of DataItem objects of the specified class, grouped by a particular field.

If the indexing field has unique values, indexedQuery() might be more appropriate.

Parameters
string$constraintsoptional constraint clause to apply to the query in the form "WHERE ... [ORDER BY ...]"
string$fieldoptional the name of the field by which to group the results

Definition at line 560 of file join.inc.

561  {
562  $field = "";
563  $idxClass = "";
564 
565  if ($indexBy != "")
566  {
567  list($idxClass, $field) = explode(".", $indexBy);
568  }
569  else
570  {
571  $idxClass = $this->class[0];
572  $obj = new $class;
573  $field = $obj->primary_key;
574  }
575 
576  trace("groupedQuery(): Group by $idxClass $field", 3);
577 
578  $query = $this->generateQuery($constraints);
579 
580  try
581  {
583  $result = $db->prepare($query);
584  $result->execute();
585 
586  $items = array();
587 
588  while($line = $result->fetch())
589  {
590  $item = new JoinResult($this->tag);
591 
592  for($i = 0; $i < count($this->classes); ++$i)
593  {
594  $class = $this->classes[$i];
595  $item->$class = new $class;
596  $item->$class->populate($line, $this->aliases[$item->$class->table]);
597 
598  foreach($this->pseudos as $class => $lookup)
599  {
600  foreach($this->aliases as $table => $prefix)
601  {
602  $keyAlias = "{$prefix}.{$lookup['index']}";
603 
604  $key = $line[$keyAlias];
605 
606  if (array_key_exists($key, $lookup['items']))
607  {
608  $item->$class = $lookup['items'][$key];
609  break;
610  }
611  }
612  }
613  }
614 
615  $idx = $item->$idxClass->$field;
616  $items[$idx][] = $item;
617  }
618 
619  unset($result);
620 
621  return $items;
622  }
623  catch(PDOException $e)
624  {
625  throw new FakoliException($e->getMessage());
626  }
627  }
count($constraints="", $countExpr=true)
Definition: join.inc:356
JoinResult is an empty placeholder class.
Definition: join.inc:46

◆ indexedQuery()

AbstractJoin::indexedQuery (   $constraints = "",
  $indexBy = "" 
)

Performs a query against the database, returning an array of DataItem objects of the specified class, indexed by a particular field.

If more than one item is found that matches the same value of the indexing field, the results entry is promoted to an array automatically. However, in cases where this is common, using groupedQuery() might simplify your calling code.

Parameters
string$constraintsoptional constraint clause to apply to the query in the form "WHERE ... [ORDER BY ...]"
string$fieldoptional the name of the field by which to index the results (See InclusionFilter and ExclusionFilter)

Definition at line 475 of file join.inc.

476  {
477  $field = "";
478  $idxClass = "";
479 
480  if ($indexBy != "")
481  {
482  list($idxClass, $field) = explode(".", $indexBy);
483  }
484  else
485  {
486  $idxClass = $this->class[0];
487  $obj = new $class;
488  $field = $obj->primary_key;
489  }
490 
491  $query = $this->generateQuery($constraints);
492 
493  try
494  {
496  $result = $db->prepare($query);
497  $result->execute();
498 
499  $items = array();
500 
501  while($line = $result->fetch())
502  {
503  $item = new JoinResult($this->tag);
504 
505  for($i = 0; $i < count($this->classes); ++$i)
506  {
507  $class = $this->classes[$i];
508  $item->$class = new $class;
509  $item->$class->populate($line, $this->aliases[$item->$class->table]);
510 
511  foreach($this->pseudos as $class => $lookup)
512  {
513  foreach($this->aliases as $table => $prefix)
514  {
515  $keyAlias = "{$prefix}.{$lookup['index']}";
516 
517  $key = $line[$keyAlias];
518 
519  if (array_key_exists($key, $lookup['items']))
520  {
521  $item->$class = $lookup['items'][$key];
522  break;
523  }
524  }
525  }
526  }
527 
528  $idx = $item->$idxClass->$field;
529  if (array_key_exists($idx, $items))
530  {
531  // Implicitly promote to array if there is a collision
532  if (!is_array($items[$idx]))
533  {
534  $items[$idx] = array($items[$idx]);
535  }
536  $items[$idx][] = $item;
537  }
538  else
539  {
540  $items[$idx] = $item;
541  }
542  }
543 
544  unset($result);
545 
546  return $items;
547  }
548  catch(PDOException $e)
549  {
550  throw new FakoliException($e->getMessage());
551  }
552  }

◆ iteratedQuery()

AbstractJoin::iteratedQuery (   $constraints = "")

Performs a query against the database returning an iterator of JoinResult objects.

Parameters
string$constraints

Definition at line 461 of file join.inc.

462  {
463  return new JoinResultIterator($this, $constraints);
464  }

◆ pseudo()

AbstractJoin::pseudo (   $class,
  $items,
  $indexField 
)

Registers a class and indexed array as a pseudo-join item.

Pseudo-joins are joined into the result set based on the supplied index field.

Parameters
string$classClass name for the items being joined
array$itemsarray of DataItems indexed by the joining key (usually the primary key)
string$indexFieldthe field to be joined on

Definition at line 349 of file join.inc.

350  {
351  $this->pseudos[$class] = array("index" => $indexField, "items" => $items);
352  }

◆ query()

AbstractJoin::query (   $constraints = "",
  $page = -1,
  $size = -1 
)

Performs a query against the database returning an array of JoinResult objects.

Parameters
string$constraints
integer$page
integer$size

Definition at line 387 of file join.inc.

388  {
389  $query = $this->generateQuery($constraints);
390 
391  try
392  {
394  $result = $db->prepare($query);
395  $result->execute();
396 
397  if ($page > 0)
398  {
399  $count = ($page - 1) * $size;
400  while($count--)
401  {
402  $result->fetch();
403  }
404  }
405 
406  $items = array();
407 
408  while($line = $result->fetch())
409  {
410  $item = new JoinResult($this->tag);
411 
412  for($i = 0; $i < count($this->classes); ++$i)
413  {
414  $class = $this->classes[$i];
415  $item->$class = new $class;
416  $item->$class->populate($line, $this->aliases[$item->$class->table]);
417 
418  foreach($this->pseudos as $class => $lookup)
419  {
420  foreach($this->aliases as $table => $prefix)
421  {
422  $keyAlias = "{$prefix}.{$lookup['index']}";
423 
424  if (!array_key_exists($keyAlias, $line)) continue;
425 
426  $key = $line[$keyAlias];
427 
428  //trace("$keyAlias = {$key}", 3);
429  //trace(print_r(array_keys($line), true), 3);
430 
431  if (array_key_exists($key, $lookup['items']))
432  {
433  //trace("Pseudo Match found for $keyAlias = $key",3);
434  $item->$class = $lookup['items'][$key];
435  break;
436  }
437  }
438  }
439 
440  --$size;
441  if ($size == 0) break;
442  }
443 
444  $items[] = $item;
445  }
446 
447  unset($result);
448 
449  return $items;
450  }
451  catch(PDOException $e)
452  {
453  throw new FakoliException($e->getMessage());
454  }
455  }

◆ setFilter()

AbstractJoin::setFilter (   $class,
  $filter 
)

Sets an InclusionFilter or ExclusionFilter on the specified class.

Parameters
$classthe class to be filtered
$filterInclusionFilter or ExclusionFilter object defining the sub-set of fields to include

Definition at line 285 of file join.inc.

286  {
287  $this->protos[$class]->filter = $filter;
288  return $this;
289  }

◆ xref()

AbstractJoin::xref (   $xref,
  $xrefFieldMaps = null 
)

Adds a cross-reference class to the join definition.

Classes added using this method are NOT included in the eventual result set.

Parameters
$xref
$xrefFieldMaps

Definition at line 330 of file join.inc.

331  {
332  $x = new $xref;
333 
334  $this->xrefs[] = $x;
335 
336  if ($xrefFieldMaps)
337  {
338  $this->xrefFieldMaps[$x->table] = $xrefFieldMaps;
339  }
340  }
$xrefFieldMaps
Cross-reference field map (to support cross-referencing through fields with differing names)
Definition: join.inc:238

Member Data Documentation

◆ $aliases

AbstractJoin::$aliases = array()

Field aliases for output.

Definition at line 240 of file join.inc.

◆ $classes

AbstractJoin::$classes = array()

The names of the DataItem classes being joined.

Definition at line 234 of file join.inc.

◆ $constraints

AbstractJoin::$constraints = array()

Class-specific constraints add via the constrain() method.

Definition at line 242 of file join.inc.

◆ $excludedKeys

AbstractJoin::$excludedKeys = array()

Definition at line 247 of file join.inc.

◆ $protos

AbstractJoin::$protos = array()

Prototype instances of the DataItem classes being joined.

Definition at line 235 of file join.inc.

◆ $pseudos

AbstractJoin::$pseudos = array()

Pseudo-join lookup tables.

Definition at line 248 of file join.inc.

◆ $tag

AbstractJoin::$tag = "join"

XML tag name.

Definition at line 245 of file join.inc.

◆ $unique

AbstractJoin::$unique = false

true to output distinct rows only

Definition at line 244 of file join.inc.

◆ $xrefAliases

AbstractJoin::$xrefAliases = array()

Cross-reference table aliases.

Definition at line 241 of file join.inc.

◆ $xrefFieldMaps

AbstractJoin::$xrefFieldMaps = array()

Cross-reference field map (to support cross-referencing through fields with differing names)

Definition at line 238 of file join.inc.

◆ $xrefs

AbstractJoin::$xrefs = array()

Cross-reference classes (i.e. classes that are part of the join, but not the result)

Definition at line 236 of file join.inc.


The documentation for this class was generated from the following file: