Click here to Skip to main content
15,891,316 members
Articles / Database Development / SQL Server

A scripted SQL query generation framework with IDE: SQLpp (v1.4)

Rate me:
Please Sign up or sign in to vote.
4.98/5 (47 votes)
12 Sep 200311 min read 413K   5.4K   133  
A helper framework for generation of SQL queries in C++ and Lua
#include <sqlpp/database.hpp>
#include <sqlpp/ref_constraint.hpp>
#include <sqlpp/queries/select_query.hpp>

namespace sqlpp{

	database::database( adaptors::database_adaptor_shared_ptr adaptor_)
	: m_adaptor(adaptor_)
	{
		if (!m_adaptor)
			throw exceptions::sqlpp_exception("adaptor pointer is null");
	};

	adaptors::database_adaptor_shared_ptr database::get_adaptor() const	
	{	
		return m_adaptor;
	};
	
	void database::set_adaptor( adaptors::database_adaptor_shared_ptr adap_ )
	{
		if (!adap_)
			throw exceptions::sqlpp_exception("adaptor pointer is null");

		m_adaptor = adap_;
	};


	size_t database::get_table_size() const
	{	
		return m_tables.size();
	};


	database_shared_ptr database::create(adaptors::database_adaptor_shared_ptr adaptor_)
	{	
		if (!adaptor_)
			throw exceptions::sqlpp_exception("database::create: adaptor pointer is null");

		database_shared_ptr db(new database(adaptor_));
		if (!db)
			throw exceptions::sqlpp_exception("database::create: memory allocation error");
		return db;
	};

	queries::select_query_shared_ptr database::create_query( )
	{
		queries::select_query_shared_ptr q( 
			new queries::select_query(
				shared_from_this(), 
				false
				) 
			);
		if (!q)
			throw exceptions::sqlpp_exception("database::create_query: memory allocation error");
		return q;
	};

	bool database::contains_table(string_const_reference name_) const
	{
		table_id_map_type::const_iterator it = std::find_if(
			m_tables.begin(),
			m_tables.end(),
			details::is_name_equal_first(name_)
			);

		return it != m_tables.end();
	};
	bool database::contains_table(properties::id_type id_) const
	{
		table_id_map_type::const_iterator it = m_tables.find(id_);
		return it != m_tables.end();
	};

	table_shared_ptr database::get_table( string_const_reference name_) const
	{
		table_id_map_type::const_iterator it = std::find_if(
			m_tables.begin(),
			m_tables.end(),
			details::is_name_equal_first(name_)
			);

		if ( it == m_tables.end())
			throw exceptions::sqlpp_exception("database::get_table: could not find table " + name_);

		return it->second.first;
	};

	table_shared_ptr database::get_table( properties::id_type id_) const
	{
		table_id_map_type::const_iterator it = m_tables.find(id_);

		if ( it == m_tables.end())
			throw exceptions::sqlpp_exception("database::get_table: could not find table ");
		
		return it->second.first;
	};

	table_shared_ptr database::add_table( 
		string_const_reference name_,
		string_const_reference field_prefix_
		)
	{
		if (contains_table(name_))
			throw exceptions::sqlpp_exception("database::add_table: duplicate table name " + name_);

		table_shared_ptr table(
			new table(
				shared_from_this(),
				name_, 
				field_prefix_
				)
			);
		if (!table)
			throw exceptions::sqlpp_exception("database::add_table: memory allocation error");

		// adding to graph
		graphs::table_map_t table_map = boost::get( graphs::vertex_table, m_table_graph );
		graphs::table_vertex_t u = boost::add_vertex(m_table_graph);
		table_map[u] = table->get_id();

		// adding to map
		m_tables[table->get_id()]=table_vertex_type(table,u);

		return table;
	};

	void database::join_tables(
			ref_constraint_shared_ptr ref_
		)
	{
		using namespace properties;
		using namespace graphs;

		if (!ref_)
			throw exceptions::sqlpp_exception("database::join_tables: reference constraint is null");

		// get graph vertices
		id_type id_source=ref_->get_table()->get_id();
		id_type id_target=ref_->get_reference_table()->get_id();

		// get vertex
		table_id_map_type::const_iterator it_source = m_tables.find(id_source);
		if (it_source == m_tables.end())
			throw exceptions::sqlpp_exception("database::join_tables: source table not found in database");
		table_id_map_type::const_iterator it_target = m_tables.find(id_target);
		if (it_target == m_tables.end())
			throw exceptions::sqlpp_exception("database::join_tables: target table not found in database");

		// add edge
		table_edge_t e;
		bool inserted;
		boost::tie(e,inserted) = boost::add_edge( it_source->second.second, it_target->second.second, m_table_graph);
	
		if (!inserted)
			throw exceptions::sqlpp_exception("database::join_tables: could not insert edge");

		graphs::ref_map_t edge_map = boost::get( graphs::edge_ref, m_table_graph );
		edge_map[e]=ref_;
	
		m_edge_map[ref_->get_id()]=e;
	}

	ref_constraint_container database::find_refs( table_shared_ptr source_, table_shared_ptr target_) const
	{
		if (!source_)
			throw exceptions::sqlpp_exception("database::find_refs: source table is null");
		if (!target_)
			throw exceptions::sqlpp_exception("database::find_refs: target table is null");

		// get vertex
		table_id_map_type::const_iterator it_source = m_tables.find(source_->get_id());
		if (it_source == m_tables.end())
			throw exceptions::sqlpp_exception("database::find_refs: could not find source table in database");
		table_id_map_type::const_iterator it_target = m_tables.find(target_->get_id());
		if (it_target == m_tables.end())
			throw exceptions::sqlpp_exception("database::find_refs: could not find target table in database");

		boost::graph_traits< graphs::table_graph >::out_edge_iterator it, it_end;
		ref_constraint_container ref_c;
		graphs::ref_const_map_t edge_map = boost::get( graphs::edge_ref, m_table_graph );
	
		for (
			boost::tie(it, it_end) = boost::out_edges(it_source->second.second,m_table_graph);
			it != it_end;
			++it
			)
		{
			if ( boost::target(*it, m_table_graph) == it_target->second.second)
				ref_c.push_back( edge_map[*it] );
		}

		return ref_c;
	}


	string_type database::get_create_statement() const
	{
		std::ostringstream out;
		string_type s;

		table_id_map_type::const_iterator it;
		for (
			it = m_tables.begin();
			it != m_tables.end();
			++it
			)
		{
			out<<it->second.first->get_create_statement()
			   <<std::endl;
		}

		if (m_adaptor->support_forward_declaration())
			return out.str();

		for (
			it = m_tables.begin();
			it != m_tables.end();
			++it
			)
		{
			s=it->second.first->get_alter_create_statement();
			if (!s.empty())
			{
				out<<"// table "<<it->second.first->get_name()<<" constraints"<<std::endl
				   <<s
				   <<std::endl;
			}
		}

		return out.str();
	}

};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Engineer
United States United States
Jonathan de Halleux is Civil Engineer in Applied Mathematics. He finished his PhD in 2004 in the rainy country of Belgium. After 2 years in the Common Language Runtime (i.e. .net), he is now working at Microsoft Research on Pex (http://research.microsoft.com/pex).

Comments and Discussions