示例#1
0
dbgTargetInfo::dbgTargetInfo( const wxString &target,  dbgPgConn *conn, char targetType )
{
	wxString query =
	    wxT("select t.*, ")
	    wxT("  pg_catalog.oidvectortypes( t.argtypes ) as argtypenames, t.argtypes as argtypeoids,")
	    wxT("  l.lanname, n.nspname, p.proretset, y.typname AS rettype")
	    wxT(" from")
	    wxT("  pldbg_get_target_info( '%s', '%c' ) t , pg_namespace n, pg_language l, pg_proc p, pg_type y")
	    wxT(" where")
	    wxT("  n.oid = t.schema and ")
	    wxT("  l.oid = t.targetlang and " )
	    wxT("  p.oid = t.target and ")
	    wxT("  y.oid = t.returntype");

	dbgResultset *result = new dbgResultset(conn->waitForCommand(wxString::Format(query, target.c_str(), targetType)));

	if(result->getCommandStatus() != PGRES_TUPLES_OK)
		throw( std::runtime_error( result->getRawErrorMessage()));

	m_name     	 = result->getString( wxString(COL_TARGET_NAME, wxConvUTF8));
	m_schema   	 = result->getString( wxString(COL_SCHEMA_NAME, wxConvUTF8));
	m_language 	 = result->getString( wxString(COL_LANGUAGE_NAME, wxConvUTF8));
	m_argNames 	 = result->getString( wxString(COL_ARG_NAMES, wxConvUTF8));
	m_argModes 	 = result->getString( wxString(COL_ARG_MODES, wxConvUTF8));
	m_argTypes 	 = result->getString( wxString(COL_ARG_TYPES, wxConvUTF8));
	m_argTypeOids = result->getString( wxString(COL_ARG_TYPEOIDS, wxConvUTF8));

	// get arg defvals if they exist
	if (result->columnExists(wxString(COL_ARG_DEFVALS, wxConvUTF8)))
		m_argDefVals = result->getString( wxString(COL_ARG_DEFVALS, wxConvUTF8));

	if (result->columnExists(wxString(COL_IS_FUNCTION, wxConvUTF8)))
		m_isFunction = result->getBool( wxString(COL_IS_FUNCTION, wxConvUTF8));
	else
		m_isFunction = true;

	m_oid      	 = result->getLong( wxString(COL_TARGET_OID, wxConvUTF8));

	if (result->columnExists(wxString(COL_PACKAGE_OID, wxConvUTF8)))
		m_pkgOid = result->getLong( wxString(COL_PACKAGE_OID, wxConvUTF8));
	else
		m_pkgOid = 0;

	m_fqName	 = result->getString( wxString(COL_FQ_NAME, wxConvUTF8));
	m_returnsSet = result->getBool( wxString(COL_RETURNS_SET, wxConvUTF8));
	m_returnType = result->getString( wxString(COL_RETURN_TYPE, wxConvUTF8));

	// Parse out the argument types, names, and modes

	// By creating a tokenizer with wxTOKEN_STRTOK and a delimiter string
	// that contains ",{}", we can parse out PostgreSQL array strings like:
	//	 {int, varchar, numeric}

	wxStringTokenizer names(m_argNames, wxT( ",{}" ), wxTOKEN_STRTOK);
	wxStringTokenizer types(m_argTypes, wxT( ",{}" ), wxTOKEN_STRTOK);
	wxStringTokenizer typeOids(m_argTypeOids, wxT( ",{}" ), wxTOKEN_STRTOK);
	wxStringTokenizer modes(m_argModes, wxT( ",{}" ), wxTOKEN_STRTOK);
	wxStringTokenizer defvals(m_argDefVals, wxT( ",{}" ), wxTOKEN_STRTOK);

	// Create one wsArgInfo for each target argument

	m_argInCount = m_argOutCount = m_argInOutCount = 0;
	int	argCount = 0;

	while( types.HasMoreTokens())
	{
		argCount++;

		wxString	argName = names.GetNextToken();
		wxString    defVal;

		if( argName.IsEmpty())
			argName.Printf( wxT( "$%d" ), argCount );

		// In EDBAS 90, if an SPL-function has both an OUT-parameter
		// and a return value (which is not possible on PostgreSQL otherwise),
		// the return value is transformed into an extra OUT-parameter
		// named "_retval_"
		if (argName == wxT("_retval_") && conn->EdbMinimumVersion(9, 0))
		{
			// this will be the return type for this object
			m_returnType = types.GetNextToken();

			// consume uniformly, mode will definitely be "OUT"
			modes.GetNextToken();

			// ignore OID also..
			typeOids.GetNextToken();
			continue;
		}

		wsArgInfo	argInfo( argName, types.GetNextToken(), modes.GetNextToken(), typeOids.GetNextToken());

		if( argInfo.getMode() == wxT( "i" ))
			m_argInCount++;
		else if( argInfo.getMode() == wxT( "o" ))
			m_argOutCount++;
		else if( argInfo.getMode() == wxT( "b" ))
			m_argInOutCount++;

		// see if this arg has a def value and add if so. If we see an empty
		// string "", what should we do? Infact "" might be a valid default
		// value in some cases, so for now store "" too. Note that we will
		// store the "" only if this is stringlike type and nothing otherwise..
		defVal = (defvals.GetNextToken()).Strip ( wxString::both );
		if (argInfo.isValidDefVal(defVal))
		{
			// remove starting/trailing quotes
			defVal.Replace( wxT( "\"" ), wxT( "" ));
			argInfo.setValue(defVal);
		}

		m_argInfo.Add( argInfo );
	}

	// Get the package initializer function OID. On 8.1 or below, this is
	// assumed to be the same as the package OID. On 8.2, we have an API :-)
	if (conn->EdbMinimumVersion(8, 2))
	{
		PGresult *res;

		m_pkgInitOid = 0;
		res = conn->waitForCommand( wxT( "SELECT pldbg_get_pkg_cons(") + NumToStr(m_pkgOid) + wxT(");"));

		if (PQresultStatus(res) == PGRES_TUPLES_OK)
		{
			// Retrieve the query result and return it.
			m_pkgInitOid = StrToLong(wxString(PQgetvalue(res, 0, 0), wxConvUTF8));

			// Cleanup & exit
			PQclear(res);
		}
	}
	else if (conn->GetIsEdb())
		m_pkgInitOid = m_pkgOid;
	else
		m_pkgInitOid = 0;
}
dbgTargetInfo::dbgTargetInfo( const wxString &target,  dbgPgConn * conn, char targetType )
{
    wxString query =
        wxT("select t.*, ")
        wxT("  pg_catalog.oidvectortypes( t.argtypes ) as argtypenames, t.argtypes as argtypeoids,")
        wxT("  l.lanname, n.nspname, p.proretset, y.typname AS rettype")
        wxT(" from")
        wxT("  pldbg_get_target_info( '%s', '%c' ) t , pg_namespace n, pg_language l, pg_proc p, pg_type y")
        wxT(" where")
        wxT("  n.oid = t.schema and ")
        wxT("  l.oid = t.targetlang and " )
        wxT("  p.oid = t.target and ")
        wxT("  y.oid = t.returntype");

    dbgResultset *result = new dbgResultset(conn->waitForCommand(wxString::Format(query, target.c_str(), targetType)));

    if(result->getCommandStatus() != PGRES_TUPLES_OK)
        throw( std::runtime_error( result->getRawErrorMessage()));

    m_name     	 = result->getString( wxString(COL_TARGET_NAME, wxConvUTF8));
    m_schema   	 = result->getString( wxString(COL_SCHEMA_NAME, wxConvUTF8));
    m_language 	 = result->getString( wxString(COL_LANGUAGE_NAME, wxConvUTF8));
    m_argNames 	 = result->getString( wxString(COL_ARG_NAMES, wxConvUTF8));
    m_argModes 	 = result->getString( wxString(COL_ARG_MODES, wxConvUTF8));
    m_argTypes 	 = result->getString( wxString(COL_ARG_TYPES, wxConvUTF8));
    m_argTypeOids = result->getString( wxString(COL_ARG_TYPEOIDS, wxConvUTF8));

    if (result->columnExists(wxString(COL_PACKAGE_OID, wxConvUTF8)))
        m_isFunction = result->getBool( wxString(COL_IS_FUNCTION, wxConvUTF8));
    else
        m_isFunction = true;

    m_oid      	 = result->getLong( wxString(COL_TARGET_OID, wxConvUTF8));

    if (result->columnExists(wxString(COL_PACKAGE_OID, wxConvUTF8)))
        m_pkgOid = result->getLong( wxString(COL_PACKAGE_OID, wxConvUTF8));
    else
        m_pkgOid = 0;

    m_fqName	 = result->getString( wxString(COL_FQ_NAME, wxConvUTF8));
    m_returnsSet = result->getBool( wxString(COL_RETURNS_SET, wxConvUTF8));
    m_returnType = result->getString( wxString(COL_RETURN_TYPE, wxConvUTF8));

    // Parse out the argument types, names, and modes

    // By creating a tokenizer with wxTOKEN_STRTOK and a delimiter string
    // that contains ",{}", we can parse out PostgreSQL array strings like:
    //	 {int, varchar, numeric}

    wxStringTokenizer names(m_argNames, wxT( ",{}" ), wxTOKEN_STRTOK);
    wxStringTokenizer types(m_argTypes, wxT( ",{}" ), wxTOKEN_STRTOK);
    wxStringTokenizer typeOids(m_argTypeOids, wxT( ",{}" ), wxTOKEN_STRTOK);
    wxStringTokenizer modes(m_argModes, wxT( ",{}" ), wxTOKEN_STRTOK);

    // Create one wsArgInfo for each target argument

    m_argInCount = m_argOutCount = m_argInOutCount = 0;
    int	argCount = 0;

    while( types.HasMoreTokens())
    {
        argCount++;

        wxString	argName = names.GetNextToken();

        if( argName.IsEmpty())
            argName.Printf( wxT( "$%d" ), argCount );

        wsArgInfo	argInfo( argName, types.GetNextToken(), modes.GetNextToken(), typeOids.GetNextToken());

        if( argInfo.getMode() == wxT( "i" ))
            m_argInCount++;
        else if( argInfo.getMode() == wxT( "o" ))
            m_argOutCount++;
        else if( argInfo.getMode() == wxT( "b" ))
            m_argInOutCount++;

        m_argInfo.Add( argInfo );
    }

    // Get the package initializer function OID. On 8.1 or below, this is
    // assumed to be the same as the package OID. On 8.2, we have an API :-)
    if (conn->EdbMinimumVersion(8, 2))
    {
        PGresult *res;

        m_pkgInitOid = 0;
        res = conn->waitForCommand( wxT( "SELECT pldbg_get_pkg_cons(") + NumToStr(m_pkgOid) + wxT(");"));

        if (PQresultStatus(res) == PGRES_TUPLES_OK)
        {
            // Retrieve the query result and return it.
            m_pkgInitOid = StrToLong(wxString(PQgetvalue(res, 0, 0), wxConvUTF8));

            // Cleanup & exit
            PQclear(res);
        }
    }
    else if (conn->GetIsEdb())
        m_pkgInitOid = m_pkgOid;
    else
        m_pkgInitOid = 0;
}