Source for file mysql.php

Documentation is available at mysql.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 MySQL(i) 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.0
  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.0
  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' .
  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 IGNORE 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.             ', ' $db->quoteName('language'')' .
  341.             ' SELECT ta.term, ta.stem, ta.common, ta.phrase, ta.term_weight, SOUNDEX(ta.term), ta.language' .
  342.             ' FROM ' $db->quoteName('#__finder_tokens_aggregate'' AS ta' .
  343.             ' WHERE ta.term_id = 0' .
  344.             ' GROUP BY ta.term'
  345.         );
  346.         $db->execute();
  347.  
  348.         /*
  349.          * Now, we just inserted a bunch of new records into the terms table
  350.          * so we need to go back and update the aggregate table with all the
  351.          * new term ids.
  352.          */
  353.         $query $db->getQuery(true)
  354.             ->update($db->quoteName('#__finder_tokens_aggregate'' AS ta')
  355.             ->join('INNER'$db->quoteName('#__finder_terms'' AS t ON t.term = ta.term')
  356.             ->set('ta.term_id = t.term_id')
  357.             ->where('ta.term_id = 0');
  358.         $db->setQuery($query);
  359.         $db->execute();
  360.  
  361.         // Mark afterTerms in the profiler.
  362.         static::$profiler static::$profiler->mark('afterTerms'null;
  363.  
  364.         /*
  365.          * After we've made sure that all of the terms are in the terms table
  366.          * and the aggregate table has the correct term ids, we need to update
  367.          * the links counter for each term by one.
  368.          */
  369.         $query->clear()
  370.             ->update($db->quoteName('#__finder_terms'' AS t')
  371.             ->join('INNER'$db->quoteName('#__finder_tokens_aggregate'' AS ta ON ta.term_id = t.term_id')
  372.             ->set('t.' $db->quoteName('links'' = t.links + 1');
  373.         $db->setQuery($query);
  374.         $db->execute();
  375.  
  376.         // Mark afterTerms in the profiler.
  377.         static::$profiler static::$profiler->mark('afterTerms'null;
  378.  
  379.         /*
  380.          * Before we can insert all of the mapping rows, we have to figure out
  381.          * which mapping table the rows need to be inserted into. The mapping
  382.          * table for each term is based on the first character of the md5 of
  383.          * the first character of the term. In php, it would be expressed as
  384.          * substr(md5(substr($token, 0, 1)), 0, 1)
  385.          */
  386.         $query->clear()
  387.             ->update($db->quoteName('#__finder_tokens_aggregate'))
  388.             ->set($db->quoteName('map_suffix'' = SUBSTR(MD5(SUBSTR(' $db->quoteName('term'', 1, 1)), 1, 1)');
  389.         $db->setQuery($query);
  390.         $db->execute();
  391.  
  392.         /*
  393.          * At this point, the aggregate table contains a record for each
  394.          * term in each context. So, we're going to pull down all of that
  395.          * data while grouping the records by term and add all of the
  396.          * sub-totals together to arrive at the final total for each token for
  397.          * this link. Then, we insert all of that data into the appropriate
  398.          * mapping table.
  399.          */
  400.         for ($i 0$i <= 15$i++)
  401.         {
  402.             // Get the mapping table suffix.
  403.             $suffix dechex($i);
  404.  
  405.             /*
  406.              * We have to run this query 16 times, one for each link => term
  407.              * mapping table.
  408.              */
  409.             $db->setQuery(
  410.                 'INSERT INTO ' $db->quoteName('#__finder_links_terms' $suffix.
  411.                 ' (' $db->quoteName('link_id'.
  412.                 ', ' $db->quoteName('term_id'.
  413.                 ', ' $db->quoteName('weight'')' .
  414.                 ' SELECT ' . (int) $linkId ', ' $db->quoteName('term_id'',' .
  415.                 ' ROUND(SUM(' $db->quoteName('context_weight''), 8)' .
  416.                 ' FROM ' $db->quoteName('#__finder_tokens_aggregate'.
  417.                 ' WHERE ' $db->quoteName('map_suffix'' = ' $db->quote($suffix.
  418.                 ' GROUP BY ' $db->quoteName('term'.
  419.                 ' ORDER BY ' $db->quoteName('term'' DESC'
  420.             );
  421.             $db->execute();
  422.         }
  423.  
  424.         // Mark afterMapping in the profiler.
  425.         static::$profiler static::$profiler->mark('afterMapping'null;
  426.  
  427.         // Update the signature.
  428.         $query->clear()
  429.             ->update($db->quoteName('#__finder_links'))
  430.             ->set($db->quoteName('md5sum'' = ' $db->quote($curSig))
  431.             ->where($db->quoteName('link_id'' = ' $db->quote($linkId));
  432.         $db->setQuery($query);
  433.         $db->execute();
  434.  
  435.         // Mark afterSigning in the profiler.
  436.         static::$profiler static::$profiler->mark('afterSigning'null;
  437.  
  438.         // Truncate the tokens tables.
  439.         $db->truncateTable('#__finder_tokens');
  440.  
  441.         // Truncate the tokens aggregate table.
  442.         $db->truncateTable('#__finder_tokens_aggregate');
  443.  
  444.         // Toggle the token tables back to memory tables.
  445.         $this->toggleTables(true);
  446.  
  447.         // Mark afterTruncating in the profiler.
  448.         static::$profiler static::$profiler->mark('afterTruncating'null;
  449.  
  450.         return $linkId;
  451.     }
  452.  
  453.     /**
  454.      * Method to remove a link from the index.
  455.      *
  456.      * @param   integer  $linkId  The id of the link.
  457.      *
  458.      * @return  boolean  True on success.
  459.      *
  460.      * @since   2.5
  461.      * @throws  Exception on database error.
  462.      */
  463.     public function remove($linkId)
  464.     {
  465.         $db JFactory::getDbo();
  466.         $query $db->getQuery(true);
  467.  
  468.         // Update the link counts and remove the mapping records.
  469.         for ($i 0$i <= 15$i++)
  470.         {
  471.             // Update the link counts for the terms.
  472.             $query->update($db->quoteName('#__finder_terms'' AS t')
  473.                 ->join('INNER'$db->quoteName('#__finder_links_terms' dechex($i)) ' AS m ON m.term_id = t.term_id')
  474.                 ->set('t.links = t.links - 1')
  475.                 ->where('m.link_id = ' $db->quote((int) $linkId));
  476.             $db->setQuery($query);
  477.             $db->execute();
  478.  
  479.             // Remove all records from the mapping tables.
  480.             $query->clear()
  481.                 ->delete($db->quoteName('#__finder_links_terms' dechex($i)))
  482.                 ->where($db->quoteName('link_id'' = ' . (int) $linkId);
  483.             $db->setQuery($query);
  484.             $db->execute();
  485.         }
  486.  
  487.         // Delete all orphaned terms.
  488.         $query->clear()
  489.             ->delete($db->quoteName('#__finder_terms'))
  490.             ->where($db->quoteName('links'' <= 0');
  491.         $db->setQuery($query);
  492.         $db->execute();
  493.  
  494.         // Delete the link from the index.
  495.         $query->clear()
  496.             ->delete($db->quoteName('#__finder_links'))
  497.             ->where($db->quoteName('link_id'' = ' $db->quote((int) $linkId));
  498.         $db->setQuery($query);
  499.         $db->execute();
  500.  
  501.         // Remove the taxonomy maps.
  502.         FinderIndexerTaxonomy::removeMaps($linkId);
  503.  
  504.         // Remove the orphaned taxonomy nodes.
  505.  
  506.         return true;
  507.     }
  508.  
  509.     /**
  510.      * Method to optimize the index. We use this method to remove unused terms
  511.      * and any other optimizations that might be necessary.
  512.      *
  513.      * @return  boolean  True on success.
  514.      *
  515.      * @since   3.0
  516.      * @throws  Exception on database error.
  517.      */
  518.     public function optimize()
  519.     {
  520.         // Get the database object.
  521.         $db JFactory::getDbo();
  522.         $query $db->getQuery(true);
  523.  
  524.         // Delete all orphaned terms.
  525.         $query->delete($db->quoteName('#__finder_terms'))
  526.             ->where($db->quoteName('links'' <= 0');
  527.         $db->setQuery($query);
  528.         $db->execute();
  529.  
  530.         // Optimize the links table.
  531.         $db->setQuery('OPTIMIZE TABLE ' $db->quoteName('#__finder_links'));
  532.         $db->execute();
  533.  
  534.         for ($i 0$i <= 15$i++)
  535.         {
  536.             // Optimize the terms mapping table.
  537.             $db->setQuery('OPTIMIZE TABLE ' $db->quoteName('#__finder_links_terms' dechex($i)));
  538.             $db->execute();
  539.         }
  540.  
  541.         // Optimize the terms mapping table.
  542.         $db->setQuery('OPTIMIZE TABLE ' $db->quoteName('#__finder_links_terms'));
  543.         $db->execute();
  544.  
  545.         // Remove the orphaned taxonomy nodes.
  546.  
  547.         // Optimize the taxonomy mapping table.
  548.         $db->setQuery('OPTIMIZE TABLE ' $db->quoteName('#__finder_taxonomy_map'));
  549.         $db->execute();
  550.  
  551.         return true;
  552.     }
  553.  
  554.     /**
  555.      * Method to add a set of tokens to the database.
  556.      *
  557.      * @param   mixed  $tokens   An array or single FinderIndexerToken object.
  558.      * @param   mixed  $context  The context of the tokens. See context constants. [optional]
  559.      *
  560.      * @return  integer  The number of tokens inserted into the database.
  561.      *
  562.      * @since   3.0
  563.      * @throws  Exception on database error.
  564.      */
  565.     protected function addTokensToDB($tokens$context '')
  566.     {
  567.         // Get the database object.
  568.         $db JFactory::getDbo();
  569.         $query $db->getQuery(true);
  570.  
  571.         // Force tokens to an array.
  572.         $tokens is_array($tokens$tokens array($tokens);
  573.  
  574.         // Count the number of token values.
  575.         $values 0;
  576.  
  577.         // Insert the tokens into the database.
  578.         $query->insert($db->quoteName('#__finder_tokens'))
  579.             ->columns(
  580.                 array(
  581.                     $db->quoteName('term'),
  582.                     $db->quoteName('stem'),
  583.                     $db->quoteName('common'),
  584.                     $db->quoteName('phrase'),
  585.                     $db->quoteName('weight'),
  586.                     $db->quoteName('context'),
  587.                     $db->quoteName('language')
  588.                 )
  589.             );
  590.  
  591.         // Iterate through the tokens to create SQL value sets.
  592.         foreach ($tokens as $token)
  593.         {
  594.             $query->values(
  595.                 $db->quote($token->term', '
  596.                     . $db->quote($token->stem', '
  597.                     . (int) $token->common ', '
  598.                     . (int) $token->phrase ', '
  599.                     . (float) $token->weight ', '
  600.                     . (int) $context ', '
  601.                     . $db->quote($token->language)
  602.             );
  603.             $values++;
  604.         }
  605.         $db->setQuery($query);
  606.         $db->execute();
  607.  
  608.         return $values;
  609.     }
  610.  
  611.     /**
  612.      * Method to switch the token tables from Memory tables to MyISAM tables
  613.      * when they are close to running out of memory.
  614.      *
  615.      * @param   boolean  $memory  Flag to control how they should be toggled.
  616.      *
  617.      * @return  boolean  True on success.
  618.      *
  619.      * @since   3.0
  620.      * @throws  Exception on database error.
  621.      */
  622.     protected function toggleTables($memory)
  623.     {
  624.         static $state;
  625.  
  626.         // Get the database adapter.
  627.         $db JFactory::getDbo();
  628.  
  629.         // Check if we are setting the tables to the Memory engine.
  630.         if ($memory === true && $state !== true)
  631.         {
  632.             // Set the tokens table to Memory.
  633.             $db->setQuery('ALTER TABLE ' $db->quoteName('#__finder_tokens'' ENGINE = MEMORY');
  634.             $db->execute();
  635.  
  636.             // Set the tokens aggregate table to Memory.
  637.             $db->setQuery('ALTER TABLE ' $db->quoteName('#__finder_tokens_aggregate'' ENGINE = MEMORY');
  638.             $db->execute();
  639.  
  640.             // Set the internal state.
  641.             $state $memory;
  642.         }
  643.         // We must be setting the tables to the MyISAM engine.
  644.         elseif ($memory === false && $state !== false)
  645.         {
  646.             // Set the tokens table to MyISAM.
  647.             $db->setQuery('ALTER TABLE ' $db->quoteName('#__finder_tokens'' ENGINE = MYISAM');
  648.             $db->execute();
  649.  
  650.             // Set the tokens aggregate table to MyISAM.
  651.             $db->setQuery('ALTER TABLE ' $db->quoteName('#__finder_tokens_aggregate'' ENGINE = MYISAM');
  652.             $db->execute();
  653.  
  654.             // Set the internal state.
  655.             $state $memory;
  656.         }
  657.  
  658.         return true;
  659.     }
  660. }

Documentation generated on Tue, 19 Nov 2013 15:09:06 +0100 by phpDocumentor 1.4.3