/*
 * Wine row server interface.
 *
 * Copyright (C) 2010 Huw Davies
 *
 * 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.1 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#pragma makedep proxy
#pragma makedep register

import "oledb.idl";


[
    threading(both),
    uuid(06210e88-01f5-11d1-b512-0080c781c384)
]
coclass PSFactoryBuffer { interface IFactoryBuffer; }

[
    object,
    uuid(38248178-cf6d-11de-abe5-000c2916d865),
    pointer_default(unique)
]
interface IWineRowServer : IUnknown
{
    [local] HRESULT SetInnerUnk([in] IUnknown *unknown);

    [local] HRESULT GetMarshal([out] IMarshal **marshal);


    /* IRow */

typedef struct
{
    DBID columnid;
    DBLENGTH max_len;
    DBTYPE type;
    BYTE precision;
    BYTE scale;
} wine_getcolumns_in;

typedef struct
{
    VARIANT v;
    DBLENGTH data_len;
    DBSTATUS status;
} wine_getcolumns_out;

    HRESULT GetColumns([in] DBORDINAL num_cols,
                       [in, size_is((ULONG)num_cols)] wine_getcolumns_in *in_data,
                       [out, size_is((ULONG)num_cols)] wine_getcolumns_out *out_cols);

    HRESULT GetSourceRowset([in] REFIID riid,
                            [out, iid_is(riid)] IUnknown **ppRowset,
                            [out] HROW *phRow);

    HRESULT Open([in, unique] IUnknown *pUnkOuter,
                 [in] DBID *pColumnID,
                 [in] REFGUID rguidColumnType,
                 [in] DWORD dwBindFlags,
                 [in] REFIID riid,
                 [out, iid_is(riid)] IUnknown **ppUnk);

    /* IRowChange */
typedef struct
{
    VARIANT v;
    DBID columnid;
    DBLENGTH data_len;
    DBSTATUS status;
    DBLENGTH max_len;
    DBTYPE type;
    BYTE precision;
    BYTE scale;
} wine_setcolumns_in;

    HRESULT SetColumns([in] DBORDINAL num_cols,
                       [in, size_is((ULONG)num_cols)] wine_setcolumns_in *in_data,
                       [out, size_is((ULONG)num_cols)] DBSTATUS *status);

    /* IRowset */
    HRESULT AddRefRows([in] DBCOUNTITEM cRows,
                       [in, size_is((ULONG)cRows)] const HROW rghRows[],
                       [out, size_is((ULONG)cRows)] DBREFCOUNT rgRefCounts[],
                       [out, size_is((ULONG)cRows)] DBROWSTATUS rgRowStatus[]);

    HRESULT GetData([in] HROW hRow,
                    [in] HACCESSOR hAccessor,
                    [in, out, size_is(size)] BYTE *pData,
                    [in] DWORD size);

    HRESULT GetNextRows([in] HCHAPTER hReserved,
                        [in] DBROWOFFSET lRowsOffset,
                        [in] DBROWCOUNT cRows,
                        [out] DBCOUNTITEM *pcRowObtained,
                        [out, size_is(,(ULONG)cRows)] HROW **prghRows);

    HRESULT ReleaseRows([in] DBCOUNTITEM cRows,
                        [in, size_is((ULONG)cRows)] const HROW rghRows[],
                        [in, size_is((ULONG)cRows)] DBROWOPTIONS rgRowOptions[],
                        [out, size_is((ULONG)cRows)] DBREFCOUNT rgRefCounts[],
                        [out, size_is((ULONG)cRows)] DBROWSTATUS rgRowStatus[]);

    HRESULT RestartPosition([in] HCHAPTER hReserved);

    /* IRowsetLocate */

    HRESULT Compare([in] HCHAPTER hReserved,
                    [in] DBBKMARK cbBookmark1,
                    [in, size_is((ULONG)cbBookmark1)] const BYTE *pBookmark1,
                    [in] DBBKMARK cbBookmark2,
                    [in, size_is((ULONG)cbBookmark2)] const BYTE *pBookmark2,
                    [out] DBCOMPARE *pComparison);

    HRESULT GetRowsAt([in] HWATCHREGION hReserved1,
                      [in] HCHAPTER hReserved2,
                      [in] DBBKMARK cbBookmark,
                      [in, size_is((ULONG)cbBookmark)] const BYTE *pBookmark,
                      [in] DBROWOFFSET lRowsOffset,
                      [in] DBROWCOUNT cRows,
                      [out] DBCOUNTITEM *pcRowsObtained,
                      [out, size_is(,(ULONG)cRows)] HROW **prghRows);

    HRESULT GetRowsByBookmark([in] HCHAPTER hReserved,
                              [in] DBCOUNTITEM cRows,
                              [in, size_is((ULONG)cRows)] const DBBKMARK rgcbBookmarks[],
                              [in, size_is((ULONG)cRows)] const BYTE *rgpBookmarks[],
                              [out, size_is((ULONG)cRows)] HROW rghRows[],
                              [out, size_is((ULONG)cRows)] DBROWSTATUS rgRowStatus[]);

    HRESULT Hash([in] HCHAPTER hReserved,
                 [in] DBBKMARK cBookmarks,
                 [in, size_is((ULONG)cBookmarks)] const DBBKMARK rgcbBookmarks[],
                 [in, size_is((ULONG)cBookmarks)] const BYTE *rgpBookmarks[],
                 [out, size_is((ULONG)cBookmarks)] DBHASHVALUE rgHashedValues[],
                 [out, size_is((ULONG)cBookmarks)] DBROWSTATUS rgBookmarkStatus[]);

    /* IRowsetInfo */

    HRESULT GetProperties([in] ULONG cPropertyIDSets,
                          [in, unique, size_is((ULONG)cPropertyIDSets)] const DBPROPIDSET *rgPropertyIDSets,
                          [in, out] ULONG *pcPropertySets,
                          [out, size_is(,*pcPropertySets)] DBPROPSET **prgPropertySets);

    HRESULT GetReferencedRowset([in] DBORDINAL iOrdinal,
                                [in] REFIID riid,
                                [out, iid_is(riid)] IUnknown **ppReferencedRowset);

    HRESULT GetSpecification([in] REFIID riid,
                             [out, iid_is(riid)] IUnknown **ppSpecification);

    /* IAccessor */

    HRESULT AddRefAccessor([in] HACCESSOR hAccessor,
                           [in, out, unique, annotation("__out_opt")] DBREFCOUNT *pcRefCount);

    HRESULT CreateAccessor([in] DBACCESSORFLAGS dwAccessorFlags,
                           [in] DBCOUNTITEM cBindings,
                           [in, unique, size_is((ULONG)cBindings)] const DBBINDING *rgBindings,
                           [in] DBLENGTH cbRowSize,
                           [out] HACCESSOR *phAccessor,
                           [in, out, unique, size_is((ULONG)cBindings)] DBBINDSTATUS *rgStatus);

    HRESULT GetBindings([in] HACCESSOR hAccessor,
                        [out] DBACCESSORFLAGS *pdwAccessorFlags,
                        [in, out] DBCOUNTITEM *pcBindings,
                        [out, size_is(,(ULONG)*pcBindings)] DBBINDING **prgBindings);

    HRESULT ReleaseAccessor([in] HACCESSOR hAccessor,
                            [in, out, unique] DBREFCOUNT *pcRefCount);
}

[
    helpstring("Wine OLE DB Row Server"),
    threading(both),
    progid("WINEDBROWPRX.AsServer.1"),
    vi_progid("WINEDBROWPRX.AsServer"),
    uuid(38248178-cf6d-11de-abe5-000c2916d865)
]
coclass wine_row_server
{

}

[
    helpstring("Wine OLE DB Row Proxy"),
    threading(both),
    progid("WINEDBROWPRX.AsProxy.1"),
    vi_progid("WINEDBROWPRX.AsProxy"),
    uuid(38248179-cf6d-11de-abe5-000c2916d865)
]
coclass wine_row_proxy
{

}

[
    helpstring("Wine OLE DB Rowset Server"),
    threading(both),
    progid("WINEDBRSTPRX.AsServer.1"),
    vi_progid("WINEDBRSTPRX.AsServer"),
    uuid(3824817a-cf6d-11de-abe5-000c2916d865)
]
coclass wine_rowset_server
{

}

[
    helpstring("Wine OLE DB Rowset Proxy"),
    threading(both),
    progid("WINEDBRSTPRX.AsProxy.1"),
    vi_progid("WINEDBRSTPRX.AsProxy"),
    uuid(3824817b-cf6d-11de-abe5-000c2916d865)
]
coclass wine_rowset_proxy
{

}

cpp_quote("extern HRESULT create_row_server( IUnknown*, LPVOID* ) DECLSPEC_HIDDEN;")
cpp_quote("extern HRESULT create_row_marshal( IUnknown*, LPVOID* ) DECLSPEC_HIDDEN;")
cpp_quote("extern HRESULT create_rowset_server( IUnknown*, LPVOID* ) DECLSPEC_HIDDEN;")
cpp_quote("extern HRESULT create_rowset_marshal( IUnknown*, LPVOID* ) DECLSPEC_HIDDEN;")
