#include "stdinc.idl"

//
// REVIEW Are we supposed to give structs guids?
//
struct SxApwColumnInfo; typedef struct SxApwColumnInfo SxApwColumnInfo;
struct SxApwColumnInfo
{
    LPCWSTR Name;
    BOOL    IsNumber;
};

cpp_quote("#if defined(__cplusplus)
extern \"C++\" {

template <typename T>
class CSxApwColumnInfoTemplate
{
public:
    void SetName(LPCWSTR name)
    {
        T::FreeString(m.Name);
        m.Name = T::DupString(name);
    }

    CSxApwColumnInfoTemplate(const CSxApwColumnInfoTemplate& that)
    {
        m.Name = T::DupString(that.m.Name);
        m.IsNumber = that.m.IsNumber;
    }

    void operator=(const CSxApwColumnInfoTemplate& that)
    {
        if (&that != this)
        {
            if (that.m.Name != NULL)
            {
                PWSTR temp = T::DupString(that.m.Name);
                if (temp == NULL)
                    return;
                T::FreeString(m.Name);
                m.Name = temp;
            }
            m.IsNumber = that.m.IsNumber;
        }
    }

    CSxApwColumnInfoTemplate() { m.Name = NULL; m.IsNumber = FALSE; }
    ~CSxApwColumnInfoTemplate() { T::FreeString(m.Name); }

    SxApwColumnInfo m;
};")
/* break up cpp_quote to avoid Midl bug that drops random characters */
cpp_quote("
class CSxApwColumnInfoTraits
{
public:
    static void   FreeString(LPCWSTR& s)
    {
        ::CoTaskMemFree(const_cast<PWSTR>(s));
        s = NULL;
    }

    static LPWSTR DupString(LPCWSTR s)
    {
        if (s == NULL)
            return NULL;
        PWSTR t = reinterpret_cast<LPWSTR>(::CoTaskMemAlloc((wcslen(s) + 1) * sizeof(*s)));
        if (t == NULL)
            return NULL;
        wcscpy(t, s);
        return t;
    }
};")
/* break up cpp_quote to avoid Midl bug that drops random characters */
cpp_quote("
typedef CSxApwColumnInfoTemplate<CSxApwColumnInfoTraits> CSxApwColumnInfo;

class CSxApwBstrColumnInfoTraits
{
public:
    static void FreeString(LPCWSTR& s)
    {
        ::SysFreeString(const_cast<BSTR>(s));
        s = NULL;
    }

    static BSTR DupString(LPCWSTR s)
    {
        if (s == NULL)
            return NULL;
        BSTR t = reinterpret_cast<BSTR>(::SysAllocString(s));
        if (t == NULL)
            return NULL;
        wcscpy(t, s);
        return t;
    }
};")
/* break up cpp_quote to avoid Midl bug that drops random characters */
cpp_quote("
typedef CSxApwColumnInfoTemplate<CSxApwBstrColumnInfoTraits> CSxApwBstrColumnInfo;
typedef CSxApwBstrColumnInfo CSxApwAdoColumnInfo;
} /* extern C++ */")
cpp_quote("#endif")

[
	object,
	uuid(IID_ISxApwHost_midl)
]
interface ISxApwHost : IUnknown
{
    HRESULT
    SetDataSource(
        [in] LPCWSTR
        );

    HRESULT
    CreateView(
        [in] LPCWSTR
        );

    HRESULT
    DestroyView(
        [in] LPCWSTR
        );

    HRESULT
    RunQuery(
        [in] LPCWSTR
        );

	HRESULT
	OnNextRow(
		[in]                    int     nColumns,
		[in, size_is(nColumns)] const LPCWSTR columns[]
		);

	HRESULT
	OnRowCountEstimateAvailable(
		[in] int
		);

    HRESULT
    OnQueryDone(
        );

    HRESULT
    InformSchema(
        [in, size_is(nColumns)] const SxApwColumnInfo   rgColumnInfo[],
        [in]    int                                     nColumns
        );
};