/* 
 * © 2007-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#ifndef _SQL_PARSER_BASE_H_
#define _SQL_PARSER_BASE_H_


#include "wbpublic_public_interface.h"
#include "grt/grt_manager.h"
#include "grtpp.h"
#include "grts/structs.db.h"


/** Encapsulates generic DBMS agnostic functionality for processing of SQL statements/scripts:
 * <li>definition of enumeration types and callbacks
 * <li>handling of errors
 * <li>GRT messaging and reporting of progress
 * 
 * @ingroup sqlparser
 */
class WBPUBLICBACKEND_PUBLIC_FUNC Sql_parser_base
{
public:
  typedef sigc::slot<int, int, int, int, const std::string &> Parse_error_cb;
  void parse_error_cb(Parse_error_cb &cb);
  Parse_error_cb & parse_error_cb();

private:
  Parse_error_cb _parse_error_cb;

protected:
  Sql_parser_base(grt::GRT *grt);
  virtual ~Sql_parser_base() {}

public:
  void case_sensitive_identifiers(bool val) { _case_sensitive_identifiers= val; }
  bool case_sensitive_identifiers() { return _case_sensitive_identifiers; }
protected:
  bool _case_sensitive_identifiers;
protected:
  std::string normalize_identifier_case(const std::string &ident);

protected:
  // aux types
  enum Parse_result { pr_irrelevant= 0, pr_processed, pr_invalid };

  // initialization
  virtual void set_options(const grt::DictRef &options);

  // state monitoring
  void add_log_message(const std::string &text, int entry_type);
  void report_sql_error(int lineno, bool calc_abs_lineno, int err_tok_line_pos, int err_tok_len, const std::string &err_msg, int entry_type, std::string resolution= "Statement skipped.");
  void step_progress(const std::string &text);
  void set_progress_state(float state, const std::string &text);

  // misc
  const std::string & sql_statement();
  virtual int total_line_count() = 0;

  // data members
  std::string _sql_statement;
  std::string _sql_script_preamble;
  size_t _processed_obj_count;
  size_t _warn_count;
  size_t _err_count;
  float _progress_state;
  grt::GRT *_grt;
  bec::GRTManager *_grtm;
  bool _messages_enabled;
  db_DatabaseObjectRef _active_obj;

  class Parse_exception : public std::exception
  {
  public:
    Parse_exception(const std::string& msg_text) : _msg_text(msg_text), _flag(2) {};
    Parse_exception(const char  *msg_text) : _msg_text(msg_text), _flag(2) {};
    virtual ~Parse_exception() THROW() {}
    const char *what() const THROW() { return _msg_text.c_str(); }
    int flag() const { return _flag; }
    void flag(int val) { _flag= val; }
  private:
    std::string _msg_text;
    int _flag;
  };

  class WBPUBLICBACKEND_PUBLIC_FUNC Null_state_keeper
  {
  public:
    Null_state_keeper(Sql_parser_base *sql_parser) : _sql_parser(sql_parser) {}
    virtual ~Null_state_keeper();
  protected:
    Sql_parser_base *_sql_parser;
  };
  friend class Null_state_keeper;
};


#endif // _SQL_PARSER_BASE_H_
