Suporte a conjuntos de linhas do esquema
Conjuntos de linhas do esquema permitem que os consumidores obter informações sobre um armazenamento de dados sem saber sua estrutura subjacente, ou esquema.Por exemplo, um armazenamento de dados pode ter tabelas organizadas em uma hierarquia definida pelo usuário, portanto, não seria nenhuma maneira de garantir conhecimento do esquema, exceto por leitura.(sistema autônomo outro exemplo, observe que sistema autônomo assistentes do Visual C++ usam conjuntos de linhas de esquema para gerar acessadores para o consumidor.) Para permitir que o consumidor fazer isso, o objeto da sessão do provedor de expõe métodos sobre o IDBSchemaRowset interface.Em aplicativos do Visual C++, você usar o IDBSchemaRowsetImpl classe de implementarIDBSchemaRowset.
IDBSchemaRowsetImpl oferece suporte aos seguintes métodos:
CheckRestrictions verifica a validade das restrições em relação a um conjunto de linhas de esquema.
CreateSchemaRowset implementa uma função de criador do objeto COM para o objeto especificado pelo parâmetro de modelo.
SetRestrictions Especifica quais restrições de suporte em um conjunto de linhas de esquema específico.
IDBSchemaRowset::GetRowset retorna um conjunto de linhas de esquema (herdado da interface).
GetSchemas retorna uma lista de conjuntos de linhas do esquema acessível por IDBSchemaRowsetImpl::GetRowset (herdado da interface).
Suporte de provedor OLE DB assistente ATL
O ATL OLE DB provedor assistente cria três classes de esquema no arquivo de cabeçalho de sessão:
CShortNameSessionTRSchemaRowset
CShortNameSessionColSchemaRowset
CShortNameSessionPTSchemaRowset
Essas classes responder a solicitações de consumidor de informações do esquema; Observe que a especificação OLE DB exige que suporte esses conjuntos de linhas do três esquema:
CShortName do SessionTRSchemaRowset lida com solicitações de informações da tabela (a DBSCHEMA_TABLES conjunto de linhas de esquema).
CShortName do SessionColSchemaRowset lida com solicitações para informações de coluna (o DBSCHEMA_COLUMNS conjunto de linhas de esquema).O assistente fornece exemplos de implementações para estas classes, que retornam informações de esquema para um provedor DOS.
CShortName do SessionPTSchemaRowset lida com solicitações para informações de esquema sobre o tipo de provedor (a DBSCHEMA_PROVIDER_TYPESconjunto de esquema linhas).A implementação padrão fornecida pelo assistente retorna S_OK.
Você pode personalizar essas classes para lidar com informações sobre o esquema apropriado para seu provedor:
In CShortNamedo SessionTRSchemaRowset, você deve preencher o catálogo, tabela e campos de descrição (trData.m_szType, trData.m_szTable, and trData.m_szDesc).O exemplo gerado pelo assistente utiliza apenas uma linha (tabela).Outros provedores podem retornar mais de uma tabela.
In CShortNamedo SessionColSchemaRowset, passe o nome da tabela sistema autônomo um DBID.
configuração Restrições
Um conceito importante no suporte ao conjunto de linhas de esquema está definindo restrições, que é usando SetRestrictions. Restrições permitem que os consumidores buscar somente as linhas correspondentes (por exemplo, localizar todas as colunas na tabela "MinhaTabela").As restrições são opcionais e no caso em que nenhum são suportadas (padrão), todos os dados sempre retorna.Para obter um exemplo de um provedor que oferece suporte a restrições, consulte o UpdatePV amostra.
Configuração do MAP de esquema
Configure um MAP de esquema sistema autônomo no sessão.h em UpdatePV:
BEGIN_SCHEMA_MAP(CUpdateSession)
SCHEMA_ENTRY(DBSCHEMA_TABLES, CUpdateSessionTRSchemaRowset)
SCHEMA_ENTRY(DBSCHEMA_COLUMNS, CUpdateSessionColSchemaRowset)
SCHEMA_ENTRY(DBSCHEMA_PROVIDER_TYPES, CUpdateSessionPTSchemaRowset)
END_SCHEMA_MAP()
Para oferecer suporte a IDBSchemaRowset deve suportarDBSCHEMA_TABLES, DBSCHEMA_COLUMNS, and DBSCHEMA_PROVIDER_TYPES.Você pode adicionar conjuntos de linhas adicionais do esquema conforme desejar.
Declarar uma classe de conjunto de linhas de esquema com um Execute método sistema autônomo CUpdateSessionTRSchemaRowset em UpdatePV:
class CUpdateSessionTRSchemaRowset :
public CSchemaRowsetImpl < CUpdateSessionTRSchemaRowset,
CTABLESRow, CUpdateSession >
...
// Execute looks like this; what pointers does the consumer use?
HRESULT Execute(DBROWCOUNT* pcRowsAffected,
ULONG cRestrictions, const VARIANT* rgRestrictions)
Observe que CUpdateSession herda do IDBSchemaRowsetImpl, para que ele tenha todos a restrição de métodos de manipulação. Usando CSchemaRowsetImpl, declarar três classes filhas (listados no MAP de esquema acima): CUpdateSessionTRSchemaRowset, CUpdateSessionColSchemaRowset, e CUpdateSessionPTSchemaRowset. Cada uma dessas classes filho possui um Execute método que manipula o seu respectivo conjunto de restrições (critérios de Pesquisar). Cada Execute método compara os valores da cRestrictions e rgRestrictions parâmetros. Consulte a descrição desses parâmetros no SetRestrictions.
Para obter mais informações sobre quais restrições correspondem a um conjunto de linhas de esquema específico, consulte a tabela de conjunto de linhas de esquema GUIDs em IDBSchemaRowset in the Referência do programador do OLE DB in the Windows SDK.
Por exemplo, se houver suporte para o TABLE_NAME restrição DBSCHEMA_TABLES, você deve fazer o seguinte:
Primeiro, pesquisar DBSCHEMA_TABLES e verá que ele oferece suporte a quatro restrições (em ordem).
Restrição de conjunto de linhas de esquema |
Restrição de valor |
---|---|
TABLE_CATALOG |
0 x 1 (1 binário) |
TABLE_SCHEMA |
0 x 2 (binário 10) |
TABLE_NAME |
0 x 4 (binário 100) |
TABLE_TYPE |
0 x 8 (1000 binário) |
Em seguida, observe que há um bit de cada restrição.Como você deseja oferecer suporte a TABLE_NAME apenas, você deve retornar 0 x 4 no rgRestrictions elemento. Se houver suporte para TABLE_CATALOG and TABLE_NAME, você retornará 0 x 5 (101 binário).
Por padrão, a implementação retorna 0 (não oferece suporte a quaisquer restrições) para qualquer solicitação.UpdatePV é um exemplo de um provedor que oferece suporte a restrições.
Exemplo
Esse código é tirado do UpdatePV amostra.UpdatePv suporta os três conjuntos de linhas do esquema necessário: DBSCHEMA_TABLES, DBSCHEMA_COLUMNS, and DBSCHEMA_PROVIDER_TYPES.sistema autônomo um exemplo de sistema autônomo implementar o suporte a esquemas no seu provedor, este tópico leva você através de implementar o DBSCHEMA_TABLE o conjunto de linhas.
Observação: |
---|
O código de exemplo pode diferir do que está listado aqui, você deve considerar o código de exemplo sistema autônomo a versão mais atualizada. |
Adicionando suporte a esquema a primeira etapa é determinar quais restrições que você pretende dar suporte.Para determinar quais restrições estão disponível para conjunto de linhas de esquema, examine a especificação OLE DB para a definição de IDBSchemaRowset.Após a definição do principal, você verá uma tabela que contém o nome do conjunto de linhas de esquema, o número de restrições e as colunas de restrição.selecionar conjunto de linhas de esquema que deseja dar suporte e anote o número de colunas de restrição e restrições.Por exemplo, DBSCHEMA_TABLES () suporta quatro restriçõesTABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and TABLE_TYPE):
void SetRestrictions(ULONG cRestrictions, GUID* rguidSchema,
ULONG* rgRestrictions)
{
for (ULONG l=0; l<cRestrictions; l++)
{
if (InlineIsEqualGUID(rguidSchema[l], DBSCHEMA_TABLES))
rgRestrictions[l] = 0x0C;
else if (InlineIsEqualGUID(rguidSchema[l], DBSCHEMA_COLUMNS))
rgRestrictions[l] = 0x04;
else if (InlineIsEqualGUID(rguidSchema[l],
DBSCHEMA_PROVIDER_TYPES))
rgRestrictions[l] = 0x00;
}
}
Um bit representa cada coluna de restrição.Se você deseja oferecer suporte a uma restrição (ou seja, você pode consultar por ele), conjunto esse bit para um 1.Se desejar oferecer suporte a uma restrição, defina esse bit como zero.A partir da linha de código acima, UpdatePV suporta o TABLE_NAME and TABLE_TYPE restrições a DBSCHEMA_TABLES conjunto de linhas. Estes são os (máscara de bit 100) do terceiro e quarta restrições (máscara de bit 1000).Portanto, a máscara de bits para UpdatePv é 1100 (ou 0x0C):
if (InlineIsEqualGUID(rguidSchema[l], DBSCHEMA_TABLES))
rgRestrictions[l] = 0x0C;
A seguir Execute função é semelhante aos conjuntos de linhas regulares. Você tem três argumentos: pcRowsAffected, cRestrictions, e rgRestrictions. The pcRowsAffected variável é um parâmetro de saída que o provedor pode retornar a contagem de linhas no conjunto de linhas de esquema. The cRestrictions parâmetro é um parâmetro de entrada que contém o número de restrições passada pelo consumidor para o provedor. The rgRestrictions parâmetro é uma matriz de VARIANTE valores que contêm os valores de restrição.
HRESULT Execute(DBROWCOUNT* pcRowsAffected, ULONG cRestrictions,
const VARIANT* rgRestrictions)
The cRestrictions variável baseia-se o número total de restrições para um conjunto de registros de esquema, independentemente de se o provedor oferece suporte-los. Como UpdatePv oferece suporte a duas restrições (a terceira e quarta), esse código somente procura por um cRestrictions valor maior que ou igual a três.
O valor para o TABLE_NAME armazenado em restriçãorgRestrictions[2] (novamente, a restrição de terceira em um array baseado em zero é 2). Você precisa verificar se a restrição não é VT_EMPTY para realmente suporte. Observe que VT_NULL não é igual a VT_EMPTY. VT_NULL Especifica um valor de restrição válida.
A definição UpdatePv de um nome da tabela é um nome de caminho totalmente qualificado para um arquivo de texto.Extrai o valor de restrição e, em seguida, tentar em em aberto o arquivo para garantir que o arquivo existe realmente.Se o arquivo não existir, retornar S_OK. Isso pode parecer um bit para trás, mas o código que realmente está informando o consumidor é o que não havia nenhuma tabela suportada pelo nome especificado.The S_OK retorne significa que o código executado corretamente.
USES_CONVERSION;
enum {
sizeOfszFile = 255
};
CTABLESRow trData;
FILE *pFile = NULL;
TCHAR szFile[ sizeOfszFile ];
errcode err = 0;
// Handle any restrictions sent to us. This only handles
// the TABLE_NAME & TABLE_TYPE restictions (the 3rd and 4th
// restrictions in DBSCHEMA_TABLES...look in IDBSchemaRowsets
// in part 2 of the prog. ref) so your restrictions are 0x08 & 0x04
// for a total of (0x0C)
if (cRestrictions >= 3 && rgRestrictions[2].vt != VT_EMPTY)
{
CComBSTR bstrName = rgRestrictions[2].bstrVal;
if ((rgRestrictions[2].vt == VT_BSTR) && (bstrName != (BSTR)NULL))
{
// Check to see if the file exists
_tcscpy_s(&szFile[0], sizeOfszFile, OLE2T(bstrName));
if (szFile[0] == _T('\0') ||
((err = _tfopen(&pFile, &szFile[0], _T("r"))) == 0))
{
return S_OK;// Their restriction was invalid return no data
}
else
{
fclose(pFile);
}
}
}
Suporte a restrição quarta (TABLE_TYPE) é semelhante a restrição de terceira.Verifique o valor não é VT_EMPTY. Essa restrição só retorna o tipo de tabela, TABELA.Para determinar os valores válido para o DBSCHEMA_TABLES, procure no Apêndice B das Referência do programador do OLE DB in the TABELAS a seção conjunto de linhas.
// TABLE_TYPE restriction:
if (cRestrictions >=4 && rgRestrictions[3].vt != VT_EMPTY)
{
CComBSTR bstrType = rgRestrictions[3].bstrVal;
if ((rgRestrictions[3].vt == VT_BSTR) && (bstrType != (BSTR)NULL))
{
// This is kind of a blind restriction.
// This only actually supports
// TABLES so if you get anything else,
// just return an empty rowset.
if (_tcscmp(_T("TABLE"), OLE2T(bstrType)) != 0)
return S_OK;
}
}
Isso é onde você realmente cria uma entrada de linha para o conjunto de linhas.A variável trData corresponde ao CTABLESRow, uma estrutura definida nos modelos de provedor OLE DB.CTABLESRow corresponde ao TABELAS definição de conjunto de linhas no Apêndice B da especificação do OLE DB.Você só tem uma linha para adicionar, porque suporta apenas uma tabela por vez.
// Bring over the data:
wcspy_s(trData.m_szType, OLESTR("TABLE"), 5);
wcspy_s(trData.m_szDesc, OLESTR("The Directory Table"), 19);
wcsncpy_s(trData.m_szTable, T2OLE(szFile), _TRUNCATE());
UpdatePV define apenas três colunas: TABLE_NAME, TABLE_TYPE, and DESCRIÇÃO.Você deve Anote as colunas para os quais você retorna informações, porque você precisará dessas informações quando você implementa GetDBStatus:
_ATLTRY
{
m_rgRowData.Add(trData);
}
_ATLCATCHALL()
{
return E_OUTOFMEMORY;
}
//if (!m_rgRowData.Add(trData))
// return E_OUTOFMEMORY;
*pcRowsAffected = 1;
return S_OK;
}
The GetDBStatus função é muito importante para a operação correta do conjunto de linhas de esquema. Porque você não retornam dados para cada coluna no TABELAS conjunto de linhas, você precisa especificar as colunas que você retornar dados para e que você não fizer isso.
virtual DBSTATUS GetDBStatus(CSimpleRow* , ATLCOLUMNINFO* pColInfo)
{
ATLASSERT(pColInfo != NULL);
switch(pColInfo->iOrdinal)
{
case 3: // TABLE_NAME
case 4: // TABLE_TYPE
case 6: // DESCRIPTION
return DBSTATUS_S_OK;
break;
default:
return DBSTATUS_S_ISNULL;
break;
}
}
Porque o seu Execute função retorna dados para o TABLE_NAME, TABLE_TYPE, and DESCRIÇÃO o camposTABELAS o conjunto de registros, você pode procurar no Apêndice B da especificação do OLE DB e determinar (contando da parte superior para baixo) que são números ordinais 3, 4 e 6.Para cada uma dessas colunas, retornar DBSTATUS_S_OK.Para todas as outras colunas, retornam DBSTATUS_S_ISNULL.É importante retornar esse status porque um consumidor não pode compreender que o valor que você retornar é NULO ou alguma outra coisa.Novamente, observe que NULO não é equivalente a branco.
Para obter mais informações sobre a interface de conjunto de linhas de esquema de OLE DB, consulte o IDBSchemaRowset interface o OLE DB Programmer Reference.
Para obter mais informações sobre como os consumidores podem usar IDBSchemaRowset métodos, consulte Obtenção de metadados com conjuntos de linhas do esquema.
Para obter um exemplo de um provedor que ofereça suporte a conjuntos de linhas do esquema, consulte o UpdatePV amostra.