/////////////////////////////////////////////////////////////////////////////
// Name:        dbserver.cpp
// Purpose:     Database Server
// Author:      Daniel Horak
// Modified by:
// RCS-ID:      $Id: dbserver.cc,v 1.3 2003/12/21 22:04:34 horakdan Exp $
// Copyright:   (c) Daniel Horak
// Licence:     GPL
/////////////////////////////////////////////////////////////////////////////

// ============================================================================
// declarations
// ============================================================================

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

// For compilers that support precompilation, includes "wx/wx.h".
#include <wx/wxprec.h>

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWindows headers
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

#include "config.h"
#include "xml.h"
#include "view.h"
#include "dbserver.h"

#include "dbsgeneric.h"
#include "dbspgsql.h"
#include "dbsmysql.h"
#include "dbsibase.h"
#include "dbsoracle.h"
#include "dbsdb2.h"

WX_DECLARE_LIST(DBServer, DBServerList);

#include <wx/listimpl.cpp>

WX_DEFINE_LIST(DBServerList);

static DBServerList *g_dbserverlist;

DBServer::DBServer(DBServerType type, const wxString& name, const wxString& version, const wxString& xslt)
	: m_type(type), m_name(name), m_version(version), m_xslt(xslt)
{
	m_stylesheet = ParseStyle(m_xslt);
}

DBServer::~DBServer()
{
#ifdef HAVE_XSLT_SUPPORT
	if (m_stylesheet)
		xsltFreeStylesheet(m_stylesheet);
#endif
}

#ifdef HAVE_XSLT_SUPPORT
xsltStylesheetPtr DBServer::ParseStyle(wxString& xslt)
{
	xsltStylesheetPtr	res = NULL;
	
#ifdef ENABLE_DEBUG
	wxLogMessage("DBServer::ParseStyle");
#endif
	if (! xslt.IsEmpty()) {
#ifdef __WXGTK__
		xslt.Prepend("/");
		xslt.Prepend(PKGDATADIR);
#endif
#ifdef ENABLE_DEBUG
		wxLogMessage("DBServer - final xslt=%s", xslt.c_str());
#endif
		if (wxFileExists(xslt)) {
			res = xsltParseStylesheetFile((const xmlChar *)xslt.c_str());
		}
		else
		{
#ifdef ENABLE_DEBUG
			wxLogMessage("DBServer::ParseStyle - style doesn't exist");
#endif
		}
	}
	
	return res;
}
#endif

bool DBServer::ExportDDL(DataDesignerView *view)
{
#ifdef ENABLE_DEBUG
	wxLogMessage("DBServer::ExportDDL");
#endif
	
#ifdef HAVE_XSLT_SUPPORT
	Transform(view, m_stylesheet);
#else
	wxMessageBox(_("Function is not supported in this build."), _("Warning"), wxOK | wxICON_WARNING);
#endif
	return TRUE;
}

#ifdef HAVE_XSLT_SUPPORT
bool DBServer::Transform(DataDesignerView *view, xsltStylesheetPtr stylesheet)
{
#ifdef ENABLE_DEBUG
	wxLogMessage("DBServer::Transform");
#endif
	
	wxDocument	*doc = view->GetDocument();
	xmlDocPtr	xmldoc, res;
	wxString	outfile;

	if (stylesheet == NULL) {
		wxMessageBox(_("Target SQL server doesn't have defined transformation stylesheet."),
		    _("Warning"), wxOK | wxICON_WARNING);
		return FALSE;
	}

	if (doc->IsModified())
		doc->Save();
	
	outfile = wxSaveFileSelector("File with SQL commands", ".sql", "output");
	xmldoc = xmlParseFile(doc->GetFilename().c_str());
	if (xmldoc == NULL)
		wxMessageBox(_("Cannot parse input file '") + doc->GetFilename() + _("'."), _("Error"), wxOK | wxICON_ERROR);
	res = xsltApplyStylesheet(stylesheet, xmldoc, NULL);
	if (res == NULL)
		wxMessageBox(_("Cannot transform input file '") + doc->GetFilename() + _("'."), _("Error"), wxOK | wxICON_ERROR);
	xsltSaveResultToFilename(outfile.c_str(), res, stylesheet, 0);
	
	xmlFreeDoc(res);
	xmlFreeDoc(xmldoc);

	return TRUE;
}
#endif

void InitServers()
{
	g_dbserverlist = new DBServerList(wxKEY_STRING);
	
	g_dbserverlist->Append("Generic",	new DBServerGeneric);
	g_dbserverlist->Append("PostgreSQL",	new DBServerPostgreSQL);
	g_dbserverlist->Append("MySQL",		new DBServerMySQL);
	g_dbserverlist->Append("InterBase",	new DBServerInterBase);
	g_dbserverlist->Append("Oracle",	new DBServerOracle);
	g_dbserverlist->Append("DB2",		new DBServerDB2);

#ifdef HAVE_XSLT_SUPPORT
//	xmlSubstituteEntitiesDefault(1);
//	xmlLoadExtDtdDefaultValue = 1;
#endif
}

void DestroyServers()
{
#ifdef HAVE_XSLT_SUPPORT
	xsltCleanupGlobals();
	xmlCleanupParser();
#endif
	delete g_dbserverlist;
}

int GetServerCount()
{
	return g_dbserverlist->GetCount();
}

wxString *GetServerNames()
{
	wxString		*names;
	wxDBServerListNode	*node;
	int			idx = 0;
	
	names = new wxString[g_dbserverlist->GetCount()];
	
	node = g_dbserverlist->GetFirst();
	while (node) {
		names[idx] = (node->GetData()->GetName());
		node = node->GetNext();
		idx++;
	}
	
	return names;
}

DBServer *GetServerByName(const wxString& name)
{
	DBServer	*server = NULL;
	wxDBServerListNode	*node;
	
#ifdef ENABLE_DEBUG
	wxLogMessage("looking for server '%s'", name.c_str());
#endif
	node = g_dbserverlist->Find(name);
	if (node) {
		server = node->GetData();
#ifdef ENABLE_DEBUG
		wxLogMessage("found server '%s'", server->GetName().c_str());
#endif
	}

	return server;
}


syntax highlighted by Code2HTML, v. 0.9.1