Source for file sqlsrv.php

Documentation is available at sqlsrv.php

  1. <?php
  2. /**
  3.  * @package     Joomla.Administrator
  4.  * @subpackage  com_finder
  5.  *
  6.  * @copyright   Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
  7.  * @license     GNU General Public License version 2 or later; see LICENSE
  8.  */
  9.  
  10. defined('_JEXEC'or die;
  11.  
  12. jimport('joomla.filesystem.file');
  13.  
  14. /**
  15.  * Indexer class supporting SQL Server for the Finder indexer package.
  16.  *
  17.  * The indexer class provides the core functionality of the Finder
  18.  * search engine. It is responsible for adding and updating the
  19.  * content links table; extracting and scoring tokens; and maintaining
  20.  * all referential information for the content.
  21.  *
  22.  * Note: All exceptions thrown from within this class should be caught
  23.  * by the controller.
  24.  *
  25.  * @package     Joomla.Administrator
  26.  * @subpackage  com_finder
  27.  * @since       3.1
  28.  */
  29. {
  30.     /**
  31.      * Method to index a content item.
  32.      *
  33.      * @param   FinderIndexerResult  $item    The content item to index.
  34.      * @param   string               $format  The format of the content. [optional]
  35.      *
  36.      * @return  integer  The ID of the record in the links table.
  37.      *
  38.      * @since   3.1
  39.      * @throws  Exception on database error.
  40.      */
  41.     public function index($item$format 'html')
  42.     {
  43.         // Mark beforeIndexing in the profiler.
  44.         static::$profiler static::$profiler->mark('beforeIndexing'null;
  45.         $db JFactory::getDbo();
  46.         $nd $db->getNullDate();
  47.  
  48.         // Check if the item is in the database.
  49.         $query $db->getQuery(true)
  50.             ->select($db->quoteName('link_id'', ' $db->quoteName('md5sum'))
  51.             ->from($db->quoteName('#__finder_links'))
  52.             ->where($db->quoteName('url'' = ' $db->quote($item->url));
  53.  
  54.         // Load the item  from the database.
  55.         $db->setQuery($query);
  56.         $link $db->loadObject();
  57.  
  58.         // Get the indexer state.
  59.         $state static::getState();
  60.  
  61.         // Get the signatures of the item.
  62.         $curSig static::getSignature($item);
  63.         $oldSig = isset($link->md5sum$link->md5sum null;
  64.  
  65.         // Get the other item information.
  66.         $linkId empty($link->link_idnull $link->link_id;
  67.         $isNew empty($link->link_idtrue false;
  68.  
  69.         // Check the signatures. If they match, the item is up to date.
  70.         if (!$isNew && $curSig == $oldSig)
  71.         {
  72.             return $linkId;
  73.         }
  74.  
  75.         /*
  76.          * If the link already exists, flush all the term maps for the item.
  77.          * Maps are stored in 16 tables so we need to iterate through and flush
  78.          * each table one at a time.
  79.          */
  80.         if (!$isNew)
  81.         {
  82.             for ($i 0$i <= 15$i++)
  83.             {
  84.                 // Flush the maps for the link.
  85.                 $query->clear()
  86.                     ->delete($db->quoteName('#__finder_links_terms' dechex($i)))
  87.                     ->where($db->quoteName('link_id'' = ' . (int) $linkId);
  88.                 $db->setQuery($query);
  89.                 $db->execute();
  90.             }
  91.  
  92.             // Remove the taxonomy maps.
  93.             FinderIndexerTaxonomy::removeMaps($linkId);
  94.         }
  95.  
  96.         // Mark afterUnmapping in the profiler.
  97.         static::$profiler static::$profiler->mark('afterUnmapping'null;
  98.  
  99.         // Perform cleanup on the item data.
  100.         $item->publish_start_date = (int) $item->publish_start_date != $item->publish_start_date $nd;
  101.         $item->publish_end_date = (int) $item->publish_end_date != $item->publish_end_date $nd;
  102.         $item->start_date = (int) $item->start_date != $item->start_date $nd;
  103.         $item->end_date = (int) $item->end_date != $item->end_date $nd;
  104.  
  105.         // Prepare the item description.
  106.         $item->description FinderIndexerHelper::parse($item->summary);
  107.  
  108.         /*
  109.          * Now, we need to enter the item into the links table. If the item
  110.          * already exists in the database, we need to use an UPDATE query.
  111.          * Otherwise, we need to use an INSERT to get the link id back.
  112.          */
  113.  
  114.         if ($isNew)
  115.         {
  116.             $columnsArray array(
  117.                 $db->quoteName('url')$db->quoteName('route')$db->quoteName('title')$db->quoteName('description'),
  118.                 $db->quoteName('indexdate')$db->quoteName('published')$db->quoteName('state')$db->quoteName('access'),
  119.                 $db->quoteName('language')$db->quoteName('type_id')$db->quoteName('object')$db->quoteName('publish_start_date'),
  120.                 $db->quoteName('publish_end_date')$db->quoteName('start_date')$db->quoteName('end_date')$db->quoteName('list_price'),
  121.                 $db->quoteName('sale_price')
  122.             );
  123.  
  124.             // Insert the link.
  125.             $query->clear()
  126.                 ->insert($db->quoteName('#__finder_links'))
  127.                 ->columns($columnsArray)
  128.                 ->values(
  129.                 $db->quote($item->url', '
  130.                 . $db->quote($item->route', '
  131.                 . $db->quote($item->title', '
  132.                 . $db->quote($item->description', '
  133.                 . $query->currentTimestamp(', '
  134.                 . '1, '
  135.                 . (int) $item->state ', '
  136.                 . (int) $item->access ', '
  137.                 . $db->quote($item->language', '
  138.                 . (int) $item->type_id ', '
  139.                 . $db->quote(serialize($item)) ', '
  140.                 . $db->quote($item->publish_start_date', '
  141.                 . $db->quote($item->publish_end_date', '
  142.                 . $db->quote($item->start_date', '
  143.                 . $db->quote($item->end_date', '
  144.                 . (double) ($item->list_price $item->list_price 0', '
  145.                 . (double) ($item->sale_price $item->sale_price 0)
  146.             );
  147.             $db->setQuery($query);
  148.             $db->execute();
  149.  
  150.             // Get the link id.
  151.             $linkId = (int) $db->insertid();
  152.         }
  153.         else
  154.         {
  155.             // Update the link.
  156.             $query->clear()
  157.                 ->update($db->quoteName('#__finder_links'))
  158.                 ->set($db->quoteName('route'' = ' $db->quote($item->route))
  159.                 ->set($db->quoteName('title'' = ' $db->quote($item->title))
  160.                 ->set($db->quoteName('description'' = ' $db->quote($item->description))
  161.                 ->set($db->quoteName('indexdate'' = ' $query->currentTimestamp())
  162.                 ->set($db->quoteName('state'' = ' . (int) $item->state)
  163.                 ->set($db->quoteName('access'' = ' . (int) $item->access)
  164.                 ->set($db->quoteName('language'' = ' $db->quote($item->language))
  165.                 ->set($db->quoteName('type_id'' = ' . (int) $item->type_id)
  166.                 ->set($db->quoteName('object'' = ' $db->quote(serialize($item)))
  167.                 ->set($db->quoteName('publish_start_date'' = ' $db->quote($item->publish_start_date))
  168.                 ->set($db->quoteName('publish_end_date'' = ' $db->quote($item->publish_end_date))
  169.                 ->set($db->quoteName('start_date'' = ' $db->quote($item->start_date))
  170.                 ->set($db->quoteName('end_date'' = ' $db->quote($item->end_date))
  171.                 ->set($db->quoteName('list_price'' = ' . (double) ($item->list_price $item->list_price 0))
  172.                 ->set($db->quoteName('sale_price'' = ' . (double) ($item->sale_price $item->sale_price 0))
  173.                 ->where('link_id = ' . (int) $linkId);
  174.             $db->setQuery($query);
  175.             $db->execute();
  176.         }
  177.  
  178.         // Set up the variables we will need during processing.
  179.         $count 0;
  180.  
  181.         // Mark afterLinking in the profiler.
  182.         static::$profiler static::$profiler->mark('afterLinking'null;
  183.  
  184.         // Truncate the tokens tables.
  185.         $db->truncateTable('#__finder_tokens');
  186.  
  187.         // Truncate the tokens aggregate table.
  188.         $db->truncateTable('#__finder_tokens_aggregate');
  189.  
  190.         /*
  191.          * Process the item's content. The items can customize their
  192.          * processing instructions to define extra properties to process
  193.          * or rearrange how properties are weighted.
  194.          */
  195.         foreach ($item->getInstructions(as $group => $properties)
  196.         {
  197.             // Iterate through the properties of the group.
  198.             foreach ($properties as $property)
  199.             {
  200.                 // Check if the property exists in the item.
  201.                 if (empty($item->$property))
  202.                 {
  203.                     continue;
  204.                 }
  205.  
  206.                 // Tokenize the property.
  207.                 if (is_array($item->$property))
  208.                 {
  209.                     // Tokenize an array of content and add it to the database.
  210.                     foreach ($item->$property as $ip)
  211.                     {
  212.                         /*
  213.                          * If the group is path, we need to a few extra processing
  214.                          * steps to strip the extension and convert slashes and dashes
  215.                          * to spaces.
  216.                          */
  217.                         if ($group === static::PATH_CONTEXT)
  218.                         {
  219.                             $ip JFile::stripExt($ip);
  220.                             $ip str_replace('/'' '$ip);
  221.                             $ip str_replace('-'' '$ip);
  222.                         }
  223.  
  224.                         // Tokenize a string of content and add it to the database.
  225.                         $count += $this->tokenizeToDB($ip$group$item->language$format);
  226.  
  227.                         // Check if we're approaching the memory limit of the token table.
  228.                         if ($count static::$state->options->get('memory_table_limit'30000))
  229.                         {
  230.                             $this->toggleTables(false);
  231.                         }
  232.                     }
  233.                 }
  234.                 else
  235.                 {
  236.                     /*
  237.                      * If the group is path, we need to a few extra processing
  238.                      * steps to strip the extension and convert slashes and dashes
  239.                      * to spaces.
  240.                      */
  241.                     if ($group === static::PATH_CONTEXT)
  242.                     {
  243.                         $item->$property JFile::stripExt($item->$property);
  244.                         $item->$property str_replace('/'' '$item->$property);
  245.                         $item->$property str_replace('-'' '$item->$property);
  246.                     }
  247.  
  248.                     // Tokenize a string of content and add it to the database.
  249.                     $count += $this->tokenizeToDB($item->$property$group$item->language$format);
  250.  
  251.                     // Check if we're approaching the memory limit of the token table.
  252.                     if ($count static::$state->options->get('memory_table_limit'30000))
  253.                     {
  254.                         $this->toggleTables(false);
  255.                     }
  256.                 }
  257.             }
  258.         }
  259.  
  260.         /*
  261.          * Process the item's taxonomy. The items can customize their
  262.          * taxonomy mappings to define extra properties to map.
  263.          */
  264.         foreach ($item->getTaxonomy(as $branch => $nodes)
  265.         {
  266.             // Iterate through the nodes and map them to the branch.
  267.             foreach ($nodes as $node)
  268.             {
  269.                 // Add the node to the tree.
  270.                 $nodeId FinderIndexerTaxonomy::addNode($branch$node->title$node->state$node->access);
  271.  
  272.                 // Add the link => node map.
  273.                 FinderIndexerTaxonomy::addMap($linkId$nodeId);
  274.  
  275.                 // Tokenize the node title and add them to the database.
  276.                 $count += $this->tokenizeToDB($node->titlestatic::META_CONTEXT$item->language$format);
  277.             }
  278.         }
  279.  
  280.         // Mark afterProcessing in the profiler.
  281.         static::$profiler static::$profiler->mark('afterProcessing'null;
  282.  
  283.         /*
  284.          * At this point, all of the item's content has been parsed, tokenized
  285.          * and inserted into the #__finder_tokens table. Now, we need to
  286.          * aggregate all the data into that table into a more usable form. The
  287.          * aggregated data will be inserted into #__finder_tokens_aggregate
  288.          * table.
  289.          */
  290.         $query    'INSERT INTO ' $db->quoteName('#__finder_tokens_aggregate'.
  291.                 ' (' $db->quoteName('term_id'.
  292.                 ', ' $db->quoteName('term'.
  293.                 ', ' $db->quoteName('stem'.
  294.                 ', ' $db->quoteName('common'.
  295.                 ', ' $db->quoteName('phrase'.
  296.                 ', ' $db->quoteName('term_weight'.
  297.                 ', ' $db->quoteName('context'.
  298.                 ', ' $db->quoteName('context_weight'.
  299.                 ', ' $db->quoteName('language'')' .
  300.                 ' SELECT' .
  301.                 ' t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context,' .
  302.                 ' ROUND( t1.weight * COUNT( t2.term ) * %F, 8 ) AS context_weight, t1.language' .
  303.                 ' FROM (' .
  304.                 '   SELECT DISTINCT t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
  305.                 '   FROM ' $db->quoteName('#__finder_tokens'' AS t1' .
  306.                 '   WHERE t1.context = %d' .
  307.                 ' ) AS t1' .
  308.                 ' JOIN ' $db->quoteName('#__finder_tokens'' AS t2 ON t2.term = t1.term' .
  309.                 ' LEFT JOIN ' $db->quoteName('#__finder_terms'' AS t ON t.term = t1.term' .
  310.                 ' WHERE t2.context = %d' .
  311.                 ' GROUP BY t1.term, t.term_id, t1.term, t1.stem, t1.common, t1.phrase, t1.weight, t1.context, t1.language' .
  312.                 ' ORDER BY t1.term DESC';
  313.  
  314.         // Iterate through the contexts and aggregate the tokens per context.
  315.         foreach ($state->weights as $context => $multiplier)
  316.         {
  317.             // Run the query to aggregate the tokens for this context..
  318.             $db->setQuery(sprintf($query$multiplier$context$context));
  319.             $db->execute();
  320.         }
  321.  
  322.         // Mark afterAggregating in the profiler.
  323.         static::$profiler static::$profiler->mark('afterAggregating'null;
  324.  
  325.         /*
  326.          * When we pulled down all of the aggregate data, we did a LEFT JOIN
  327.          * over the terms table to try to find all the term ids that
  328.          * already exist for our tokens. If any of the rows in the aggregate
  329.          * table have a term of 0, then no term record exists for that
  330.          * term so we need to add it to the terms table.
  331.          */
  332.         $db->setQuery(
  333.             'INSERT INTO ' $db->quoteName('#__finder_terms'.
  334.             ' (' $db->quoteName('term'.
  335.             ', ' $db->quoteName('stem'.
  336.             ', ' $db->quoteName('common'.
  337.             ', ' $db->quoteName('phrase'.
  338.             ', ' $db->quoteName('weight'.
  339.             ', ' $db->quoteName('soundex'')' .
  340.             ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term)' .
  341.             ' FROM ' $db->quoteName('#__finder_tokens_aggregate'' AS ta' .
  342.             ' WHERE ta.term_id IS NULL' .
  343.             ' GROUP BY ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight'
  344.         );
  345.         $db->execute();
  346.  
  347.         /*
  348.          * Now, we just inserted a bunch of new records into the terms table
  349.          * so we need to go back and update the aggregate table with all the
  350.          * new term ids.
  351.          */
  352.         $query $db->getQuery(true)
  353.             ->update('ta')
  354.             ->set('ta.term_id = t.term_id from #__finder_tokens_aggregate AS ta INNER JOIN #__finder_terms AS t ON t.term = ta.term')
  355.             ->where('ta.term_id IS NULL');
  356.         $db->setQuery($query);
  357.         $db->execute();
  358.  
  359.         // Mark afterTerms in the profiler.
  360.         static::$profiler static::$profiler->mark('afterTerms'null;
  361.  
  362.         /*
  363.          * After we've made sure that all of the terms are in the terms table
  364.          * and the aggregate table has the correct term ids, we need to update
  365.          * the links counter for each term by one.
  366.          */
  367.         $query->clear()
  368.             ->update('t')
  369.             ->set('t.links = t.links + 1 FROM #__finder_terms AS t INNER JOIN #__finder_tokens_aggregate AS ta ON ta.term_id = t.term_id');
  370.         $db->setQuery($query);
  371.         $db->execute();
  372.  
  373.         // Mark afterTerms in the profiler.
  374.         static::$profiler static::$profiler->mark('afterTerms'null;
  375.  
  376.         /*
  377.          * Before we can insert all of the mapping rows, we have to figure out
  378.          * which mapping table the rows need to be inserted into. The mapping
  379.          * table for each term is based on the first character of the md5 of
  380.          * the first character of the term. In php, it would be expressed as
  381.          * substr(md5(substr($token, 0, 1)), 0, 1)
  382.          */
  383.         $query->clear()
  384.             ->update($db->quoteName('#__finder_tokens_aggregate'))
  385.             ->set($db->quoteName('map_suffix'" = SUBSTRING(HASHBYTES('MD5', SUBSTRING(" $db->quoteName('term'', 1, 1)), 1, 1)');
  386.         $db->setQuery($query);
  387.         $db->execute();
  388.  
  389.         /*
  390.          * At this point, the aggregate table contains a record for each
  391.          * term in each context. So, we're going to pull down all of that
  392.          * data while grouping the records by term and add all of the
  393.          * sub-totals together to arrive at the final total for each token for
  394.          * this link. Then, we insert all of that data into the appropriate
  395.          * mapping table.
  396.          */
  397.         for ($i 0$i <= 15$i++)
  398.         {
  399.             // Get the mapping table suffix.
  400.             $suffix dechex($i);
  401.  
  402.             /*
  403.              * We have to run this query 16 times, one for each link => term
  404.              * mapping table.
  405.              */
  406.             $db->setQuery(
  407.                 'INSERT INTO ' $db->quoteName('#__finder_links_terms' $suffix.
  408.                 ' (' $db->quoteName('link_id'.
  409.                 ', ' $db->quoteName('term_id'.
  410.                 ', ' $db->quoteName('weight'')' .
  411.                 ' SELECT ' . (int) $linkId ', ' $db->quoteName('term_id'',' .
  412.                 ' ROUND(SUM(' $db->quoteName('context_weight''), 8)' .
  413.                 ' FROM ' $db->quoteName('#__finder_tokens_aggregate'.
  414.                 ' WHERE ' $db->quoteName('map_suffix'' = ' $db->quote($suffix.
  415.                 ' GROUP BY term, term_id' .
  416.                 ' ORDER BY ' $db->quoteName('term'' DESC'
  417.             );
  418.             $db->execute();
  419.         }
  420.  
  421.         // Mark afterMapping in the profiler.
  422.         static::$profiler static::$profiler->mark('afterMapping'null;
  423.  
  424.         // Update the signature.
  425.         $query->clear()
  426.             ->update($db->quoteName('#__finder_links'))
  427.             ->set($db->quoteName('md5sum'' = ' $db->quote($curSig))
  428.             ->where($db->quoteName('link_id'' = ' $db->quote($linkId));
  429.         $db->setQuery($query);
  430.         $db->execute();
  431.  
  432.         // Mark afterSigning in the profiler.
  433.         static::$profiler static::$profiler->mark('afterSigning'null;
  434.  
  435.         // Truncate the tokens tables.
  436.         $db->truncateTable('#__finder_tokens');
  437.  
  438.         // Truncate the tokens aggregate table.
  439.         $db->truncateTable('#__finder_tokens_aggregate');
  440.  
  441.         // Toggle the token tables back to memory tables.
  442.         $this->toggleTables(true);
  443.  
  444.         // Mark afterTruncating in the profiler.
  445.         static::$profiler static::$profiler->mark('afterTruncating'null;
  446.  
  447.         return $linkId;
  448.     }
  449.  
  450.     /**
  451.      * Method to remove a link from the index.
  452.      *
  453.      * @param   integer  $linkId  The id of the link.
  454.      *
  455.      * @return  boolean  True on success.
  456.      *
  457.      * @since   3.1
  458.      * @throws  Exception on database error.
  459.      */
  460.     public function remove($linkId)
  461.     {
  462.         $db JFactory::getDbo();
  463.         $query $db->getQuery(true);
  464.  
  465.         // Update the link counts and remove the mapping records.
  466.         for ($i 0$i <= 15$i++)
  467.         {
  468.             // Update the link counts for the terms.
  469.             $query->update('t')
  470.                 ->set('t.links = t.links - 1 from #__finder_terms AS t INNER JOIN #__finder_links_terms' dechex($i' AS AS m ON m.term_id = t.term_id')
  471.                 ->where('m.link_id = ' $db->quote((int) $linkId));
  472.             $db->setQuery($query);
  473.             $db->execute();
  474.  
  475.             // Remove all records from the mapping tables.
  476.             $query->clear()
  477.                 ->delete($db->quoteName('#__finder_links_terms' dechex($i)))
  478.                 ->where($db->quoteName('link_id'' = ' . (int) $linkId);
  479.             $db->setQuery($query);
  480.             $db->execute();
  481.         }
  482.  
  483.         // Delete all orphaned terms.
  484.         $query->clear()
  485.             ->delete($db->quoteName('#__finder_terms'))
  486.             ->where($db->quoteName('links'' <= 0');
  487.         $db->setQuery($query);
  488.         $db->execute();
  489.  
  490.         // Delete the link from the index.
  491.         $query->clear()
  492.             ->delete($db->quoteName('#__finder_links'))
  493.             ->where($db->quoteName('link_id'' = ' $db->quote((int) $linkId));
  494.         $db->setQuery($query);
  495.         $db->execute();
  496.  
  497.         // Remove the taxonomy maps.
  498.         FinderIndexerTaxonomy::removeMaps($linkId);
  499.  
  500.         // Remove the orphaned taxonomy nodes.
  501.  
  502.         return true;
  503.     }
  504.  
  505.     /**
  506.      * Method to optimize the index. We use this method to remove unused terms
  507.      * and any other optimizations that might be necessary.
  508.      *
  509.      * @return  boolean  True on success.
  510.      *
  511.      * @since   3.1
  512.      * @throws  Exception on database error.
  513.      */
  514.     public function optimize()
  515.     {
  516.         // Get the database object.
  517.         $db JFactory::getDbo();
  518.         $query $db->getQuery(true);
  519.  
  520.         // Delete all orphaned terms.
  521.         $query->delete($db->quoteName('#__finder_terms'))
  522.             ->where($db->quoteName('links'' <= 0');
  523.         $db->setQuery($query);
  524.         $db->execute();
  525.  
  526.         // Remove the orphaned taxonomy nodes.
  527.  
  528.         return true;
  529.     }
  530.  
  531.     /**
  532.      * Method to add a set of tokens to the database.
  533.      *
  534.      * @param   mixed  $tokens   An array or single FinderIndexerToken object.
  535.      * @param   mixed  $context  The context of the tokens. See context constants. [optional]
  536.      *
  537.      * @return  integer  The number of tokens inserted into the database.
  538.      *
  539.      * @since   3.1
  540.      * @throws  Exception on database error.
  541.      */
  542.     protected function addTokensToDB($tokens$context '')
  543.     {
  544.         // Get the database object.
  545.         $db JFactory::getDbo();
  546.         $query $db->getQuery(true);
  547.  
  548.         // Force tokens to an array.
  549.         $tokens is_array($tokens$tokens array($tokens);
  550.  
  551.         // Count the number of token values.
  552.         $values 0;
  553.  
  554.         // Set some variables to count the iterations
  555.         $totalTokens count($tokens);
  556.         $remaining   $totalTokens;
  557.         $iterations  0;
  558.         $loop        true;
  559.  
  560.         do
  561.         {
  562.             // Shift the token off the array
  563.             $token array_shift($tokens);
  564.  
  565.             $query->values(
  566.                 $db->quote($token->term', '
  567.                 . $db->quote($token->stem', '
  568.                 . (int) $token->common ', '
  569.                 . (int) $token->phrase ', '
  570.                 . (float) $token->weight ', '
  571.                 . (int) $context ', '
  572.                 . $db->quote($token->language)
  573.             );
  574.             $values++;
  575.             $iterations++;
  576.             $remaining--;
  577.  
  578.             // Run the query if we've reached 1000 iterations or there are no tokens remaining
  579.             if ($iterations == 1000 || $remaining == 0)
  580.             {
  581.                 // Insert the tokens into the database.
  582.                 $query->insert($db->quoteName('#__finder_tokens'))
  583.                     ->columns(
  584.                     array(
  585.                         $db->quoteName('term'),
  586.                         $db->quoteName('stem'),
  587.                         $db->quoteName('common'),
  588.                         $db->quoteName('phrase'),
  589.                         $db->quoteName('weight'),
  590.                         $db->quoteName('context'),
  591.                         $db->quoteName('language')
  592.                     )
  593.                 );
  594.                 $db->setQuery($query);
  595.                 $db->execute();
  596.  
  597.                 // Reset the query
  598.                 $query->clear();
  599.             }
  600.  
  601.             // If there's nothing remaining, we're done looping
  602.             if ($remaining == 0)
  603.             {
  604.                 $loop false;
  605.             }
  606.         }
  607.         while ($loop == true);
  608.  
  609.         return $values;
  610.     }
  611.  
  612.     /**
  613.      * Method to switch the token tables from Memory tables to MyISAM tables
  614.      * when they are close to running out of memory.
  615.      *
  616.      * @param   boolean  $memory  Flag to control how they should be toggled.
  617.      *
  618.      * @return  boolean  True on success.
  619.      *
  620.      * @since   3.1
  621.      * @throws  Exception on database error.
  622.      */
  623.     protected function toggleTables($memory)
  624.     {
  625.         return true;
  626.     }
  627. }

Documentation generated on Tue, 19 Nov 2013 15:14:11 +0100 by phpDocumentor 1.4.3