Drizzled Public API Documentation

query_cache_service.cc

00001 /* 
00002  * Copyright (C) 2010 Djellel Eddine Difallah
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *   * Redistributions of source code must retain the above copyright notice,
00009  *     this list of conditions and the following disclaimer.
00010  *   * Redistributions in binary form must reproduce the above copyright notice,
00011  *     this list of conditions and the following disclaimer in the documentation
00012  *     and/or other materials provided with the distribution.
00013  *   * Neither the name of Djellel Eddine Difallah nor the names of its contributors
00014  *     may be used to endorse or promote products derived from this software
00015  *     without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
00027  * THE POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include <config.h>
00031 #include <drizzled/session.h>
00032 #include "query_cache_service.h"
00033 #include <drizzled/table_list.h>
00034 
00035 using namespace std;
00036 
00037 namespace drizzled
00038 {
00039 
00040 QueryCacheService::CacheEntries QueryCacheService::cache;
00041 QueryCacheService::CachedTablesEntries QueryCacheService::cachedTables;
00042 
00043 message::Resultset *QueryCacheService::setCurrentResultsetMessage(Session *in_session)
00044 {
00045   message::Resultset *resultset= in_session->getResultsetMessage();
00046 
00047   if (unlikely(resultset == NULL))
00048   {
00049     /* Allocate and initialize a new Resultset message 
00050      * for this Session object.  Session is responsible for
00051      * deleting Resultset message when done with it.
00052      */
00053     resultset= new (nothrow) message::Resultset();
00054     in_session->setResultsetMessage(resultset);
00055 
00056     /* for Atomic purpose, reserve an entry for the following query
00057      */
00058     cache[in_session->query_cache_key]= message::Resultset();
00059   }
00060   return resultset;
00061 }
00062 
00063 void QueryCacheService::setResultsetHeader(message::Resultset &resultset,
00064                                           Session *in_session,
00065                                           TableList *in_table)
00066 {
00067   /* Set up the Select header */
00068   message::SelectHeader *header= resultset.mutable_select_header();
00069   
00070   (void) in_session;
00071 
00072   /* Extract all the tables mentioned in the query and 
00073    * add the metadata to the SelectHeader
00074    */
00075 
00076   for (TableList* tmp_table= in_table; tmp_table; tmp_table= tmp_table->next_global)
00077   {
00078     message::TableMeta *table_meta= header->add_table_meta();
00079     table_meta->set_schema_name(tmp_table->db, strlen(tmp_table->db));
00080     table_meta->set_table_name(tmp_table->table_name, strlen(tmp_table->table_name));
00081     /* Populate the cached tables hash */
00082     QueryCacheService::cachedTables[strcat(tmp_table->db, tmp_table->table_name)].push_back(in_session->query_cache_key);
00083   } 
00084 
00085   /* Extract the returned fields 
00086    * and add the field data to the SelectHeader
00087    */
00088   List<Item>::iterator it(in_session->lex().select_lex.item_list);
00089   Item *item;
00090   while ((item=it++))
00091   {
00092     SendField field;
00093     item->make_field(&field);
00094     
00095     message::FieldMeta *field_meta= header->add_field_meta();
00096     field_meta->set_field_name(field.col_name, strlen(field.col_name));    
00097     field_meta->set_schema_name(field.db_name, strlen(field.db_name));
00098     field_meta->set_table_name(field.table_name, strlen(field.table_name));
00099     field_meta->set_field_alias(field.org_col_name, strlen(field.org_col_name));
00100     field_meta->set_table_alias(field.org_table_name, strlen(field.org_table_name));
00101    }
00102 }
00103 
00104 bool QueryCacheService::addRecord(Session *in_session, List<Item> &list)
00105 {
00106   message::Resultset *resultset= in_session->getResultsetMessage();
00107   
00108   if (resultset != NULL)
00109   {
00110     message::SelectData *data= resultset->mutable_select_data();
00111     data->set_segment_id(1);
00112     data->set_end_segment(true);
00113     message::SelectRecord *record= data->add_record();
00114 
00115     List<Item>::iterator li(list);
00116     
00117     char buff[MAX_FIELD_WIDTH];
00118     String buffer(buff, sizeof(buff), &my_charset_bin);
00119     
00120     Item *current_field;
00121     while ((current_field= li++))
00122     {
00123       if (current_field->is_null())
00124       {
00125         record->add_is_null(true);
00126         record->add_record_value("", 0);
00127       } 
00128       else 
00129       {
00130         String *string_value= current_field->val_str(&buffer);
00131         record->add_is_null(false);
00132         record->add_record_value(string_value->c_ptr(), string_value->length());
00133         string_value->free();
00134       }
00135     }
00136     return false;
00137   }
00138   return true;
00139 }
00140 
00141 bool QueryCacheService::isCached(string query)
00142 {
00143   CacheEntries::iterator it= QueryCacheService::cache.find(query);
00144   if (it != QueryCacheService::cache.end())
00145      return true;
00146   return false;
00147 }
00148 } /* namespace drizzled */