Drizzled Public API Documentation

table_function.cc
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2010 Monty Taylor
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018  */
00019 
00020 #include <config.h>
00021 
00022 #include <drizzled/current_session.h>
00023 #include <drizzled/gettext.h>
00024 #include <drizzled/global_charset_info.h>
00025 #include <drizzled/plugin/table_function.h>
00026 #include <drizzled/session.h>
00027 #include <drizzled/show.h>
00028 #include <drizzled/table_function_container.h>
00029 #include <drizzled/sql_lex.h>
00030 
00031 #include <vector>
00032 
00033 namespace drizzled {
00034 
00035 static TableFunctionContainer table_functions;
00036 
00037 void plugin::TableFunction::init()
00038 {
00039   drizzled::message::table::init(proto, getTableLabel(), identifier.getSchemaName(), "FunctionEngine");
00040   proto.set_type(drizzled::message::Table::FUNCTION);
00041   proto.set_creation_timestamp(0);
00042   proto.set_update_timestamp(0);
00043   message::set_is_replicated(proto, false);
00044 }
00045 
00046 bool plugin::TableFunction::addPlugin(plugin::TableFunction *tool)
00047 {
00048   assert(tool != NULL);
00049   table_functions.addFunction(tool);
00050   return false;
00051 }
00052 
00053 plugin::TableFunction *plugin::TableFunction::getFunction(const std::string &arg)
00054 {
00055   return table_functions.getFunction(arg);
00056 }
00057 
00058 void plugin::TableFunction::getNames(const std::string &arg,
00059                                      std::set<std::string> &set_of_names)
00060 {
00061   table_functions.getNames(arg, set_of_names);
00062 }
00063 
00064 LEX& plugin::TableFunction::Generator::lex()
00065 {
00066   return getSession().lex();
00067 }
00068 
00069 statement::Statement& plugin::TableFunction::Generator::statement()
00070 {
00071   return *lex().statement;
00072 }
00073 
00074 plugin::TableFunction::Generator *plugin::TableFunction::generator(Field **arg)
00075 {
00076   return new Generator(arg);
00077 }
00078 
00079 void plugin::TableFunction::add_field(const char *label,
00080                                       uint32_t field_length)
00081 {
00082   add_field(label, TableFunction::STRING, field_length);
00083 }
00084 
00085 void plugin::TableFunction::add_field(const char *label,
00086                               TableFunction::ColumnType type,
00087                               bool is_default_null)
00088 {
00089   add_field(label, type, 5, is_default_null);
00090 }
00091 
00092 void plugin::TableFunction::add_field(const char *label,
00093                                       TableFunction::ColumnType type,
00094                                       uint32_t field_length,
00095                                       bool is_default_null)
00096 {
00097   drizzled::message::Table::Field *field;
00098   drizzled::message::Table::Field::FieldOptions *field_options;
00099   drizzled::message::Table::Field::FieldConstraints *field_constraints;
00100 
00101   field= proto.add_field();
00102   field->set_name(label);
00103 
00104   field_options= field->mutable_options();
00105   field_constraints= field->mutable_constraints();
00106   field_options->set_default_null(is_default_null);
00107   field_constraints->set_is_notnull(not is_default_null);
00108 
00109   switch (type)
00110   {
00111   case TableFunction::STRING:
00112     {
00113       drizzled::message::Table::Field::StringFieldOptions *string_field_options;
00114       if (field_length >= TABLE_FUNCTION_BLOB_SIZE)
00115       {
00116         field->set_type(drizzled::message::Table::Field::BLOB);
00117         string_field_options= field->mutable_string_options();
00118         string_field_options->set_collation_id(default_charset_info->number);
00119         string_field_options->set_collation(default_charset_info->name);
00120       }
00121       else
00122       {
00123         field->set_type(drizzled::message::Table::Field::VARCHAR);
00124         string_field_options= field->mutable_string_options();
00125         string_field_options->set_length(field_length);
00126       }
00127     }
00128     break;
00129   case TableFunction::VARBINARY:
00130     {
00131       drizzled::message::Table::Field::StringFieldOptions *string_field_options;
00132       field->set_type(drizzled::message::Table::Field::VARCHAR);
00133 
00134       string_field_options= field->mutable_string_options();
00135       string_field_options->set_length(field_length);
00136       string_field_options->set_collation(my_charset_bin.csname);
00137       string_field_options->set_collation_id(my_charset_bin.number);
00138     }
00139     break;
00140   case TableFunction::NUMBER:
00141     field->set_type(drizzled::message::Table::Field::BIGINT);
00142     break;
00143   case TableFunction::SIZE:
00144     field->set_type(drizzled::message::Table::Field::BIGINT);
00145     field_constraints->set_is_unsigned(true);
00146     break;
00147   case TableFunction::BOOLEAN: // Currently BOOLEAN always has a value
00148     field->set_type(drizzled::message::Table::Field::BOOLEAN);
00149     field_constraints->set_is_unsigned(true);
00150     break;
00151   }
00152 }
00153 
00154 plugin::TableFunction::Generator::Generator(Field **arg) :
00155   columns(arg),
00156   session(current_session)
00157 {
00158   scs= system_charset_info;
00159 }
00160 
00161 bool plugin::TableFunction::Generator::sub_populate(uint32_t field_size)
00162 {
00163   bool ret;
00164   uint64_t difference;
00165 
00166   columns_iterator= columns;
00167   ret= populate();
00168   difference= columns_iterator - columns;
00169 
00170   if (ret == true)
00171   {
00172     assert(difference == field_size);
00173   }
00174 
00175   return ret;
00176 }
00177 
00178 void plugin::TableFunction::Generator::push(uint64_t arg)
00179 {
00180   (*columns_iterator)->store(static_cast<int64_t>(arg), true);
00181   (*columns_iterator)->set_notnull();
00182   columns_iterator++;
00183 }
00184 
00185 void plugin::TableFunction::Generator::push(int64_t arg)
00186 {
00187   (*columns_iterator)->store(arg, false);
00188   (*columns_iterator)->set_notnull();
00189   columns_iterator++;
00190 }
00191 
00192 void plugin::TableFunction::Generator::push(const char *arg, uint32_t length)
00193 {
00194   assert(columns_iterator);
00195   assert(*columns_iterator);
00196   assert(arg);
00197   length= length ? length : strlen(arg);
00198 
00199   if ((*columns_iterator)->char_length() < length)
00200     length= (*columns_iterator)->char_length();
00201 
00202   (*columns_iterator)->store(arg, length, scs);
00203   (*columns_iterator)->set_notnull();
00204   columns_iterator++;
00205 }
00206 
00207 void plugin::TableFunction::Generator::push()
00208 {
00209   /* Only accept NULLs */
00210   assert((*columns_iterator)->maybe_null());
00211   (*columns_iterator)->set_null();
00212   columns_iterator++;
00213 }
00214 
00215 void plugin::TableFunction::Generator::push(const std::string& arg)
00216 {
00217   push(arg.c_str(), arg.length());
00218 }
00219 
00220 void plugin::TableFunction::Generator::push(bool arg)
00221 {
00222   if (arg)
00223   {
00224     (*columns_iterator)->store("YES", 3, scs);
00225   }
00226   else
00227   {
00228     (*columns_iterator)->store("NO", 2, scs);
00229   }
00230 
00231   columns_iterator++;
00232 }
00233 
00234 bool plugin::TableFunction::Generator::isWild(const std::string &predicate)
00235 {
00236   if (not lex().wild)
00237     return false;
00238 
00239   bool match= wild_case_compare(system_charset_info,
00240                                 predicate.c_str(),
00241                                 lex().wild->ptr());
00242 
00243   return match;
00244 }
00245 
00246 } /* namespace drizzled */