|
|
|
|
using System.IO;
|
|
|
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
|
|
|
|
|
|
|
|
namespace EntityFrameworkCore.Jet.Data.Tests
|
|
|
|
|
{
|
|
|
|
|
// TODO: Call all tests for ODBC and OLE DB.
|
|
|
|
|
[TestClass]
|
|
|
|
|
public class JetInformationSchemaTest
|
|
|
|
|
{
|
|
|
|
|
private const string StoreName = nameof(JetInformationSchemaTest) + ".accdb";
|
|
|
|
|
|
|
|
|
|
[ClassInitialize]
|
|
|
|
|
public static void TestFixtureSetup(TestContext context)
|
|
|
|
|
{
|
|
|
|
|
using var connection = Helpers.CreateAndOpenDatabase(StoreName);
|
|
|
|
|
|
|
|
|
|
var scriptPath = Path.Combine(Path.GetDirectoryName(typeof(JetInformationSchemaTest).Assembly.Location) ?? string.Empty, "Northwind.sql");
|
|
|
|
|
var script = File.ReadAllText(scriptPath);
|
|
|
|
|
Helpers.ExecuteScript(connection, script);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[ClassCleanup]
|
|
|
|
|
public static void TestFixtureTearDown()
|
|
|
|
|
{
|
|
|
|
|
Helpers.DeleteDatabase(StoreName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void AssertDataReaderContent(string actual, string expected)
|
|
|
|
|
=> Assert.AreEqual(expected.Trim(), actual);
|
|
|
|
|
|
|
|
|
|
[DataTestMethod]
|
|
|
|
|
[DataRow(DataAccessProviderType.Odbc)]
|
|
|
|
|
[DataRow(DataAccessProviderType.OleDb)]
|
|
|
|
|
public void Tables(DataAccessProviderType providerType)
|
|
|
|
|
{
|
|
|
|
|
using var connection = Helpers.OpenDatabase(StoreName, providerType);
|
|
|
|
|
var result = Helpers.GetDataReaderContent(connection, @"SELECT * FROM `INFORMATION_SCHEMA.TABLES`
|
|
|
|
|
WHERE TABLE_TYPE <> 'SYSTEM TABLE'
|
|
|
|
|
ORDER BY TABLE_NAME");
|
|
|
|
|
|
|
|
|
|
AssertDataReaderContent(result, $@"
|
|
|
|
|
`TABLE_NAME` | `TABLE_TYPE` | `VALIDATION_RULE` | `VALIDATION_TEXT`
|
|
|
|
|
--- | --- | --- | ---
|
|
|
|
|
{JetConnection.DefaultDualTableName} | INTERNAL TABLE | |
|
|
|
|
|
Alphabetical list of products | VIEW | |
|
|
|
|
|
Categories | BASE TABLE | |
|
|
|
|
|
Category Sales for 1997 | VIEW | |
|
|
|
|
|
Current Product List | VIEW | |
|
|
|
|
|
Customer and Suppliers by City | VIEW | |
|
|
|
|
|
CustomerCustomerDemo | BASE TABLE | |
|
|
|
|
|
CustomerDemographics | BASE TABLE | |
|
|
|
|
|
Customers | BASE TABLE | |
|
|
|
|
|
Employees | BASE TABLE | |
|
|
|
|
|
EmployeeTerritories | BASE TABLE | |
|
|
|
|
|
Invoices | VIEW | |
|
|
|
|
|
Order Details | BASE TABLE | |
|
|
|
|
|
Order Details Extended | VIEW | |
|
|
|
|
|
Order Subtotals | VIEW | |
|
|
|
|
|
Orders | BASE TABLE | |
|
|
|
|
|
Orders Qry | VIEW | |
|
|
|
|
|
Product Sales for 1997 | VIEW | |
|
|
|
|
|
Products | BASE TABLE | |
|
|
|
|
|
Products Above Average Price | VIEW | |
|
|
|
|
|
Products by Category | VIEW | |
|
|
|
|
|
Quarterly Orders | VIEW | |
|
|
|
|
|
Region | BASE TABLE | |
|
|
|
|
|
Sales by Category | VIEW | |
|
|
|
|
|
Sales Totals by Amount | VIEW | |
|
|
|
|
|
Shippers | BASE TABLE | |
|
|
|
|
|
Summary of Sales by Quarter | VIEW | |
|
|
|
|
|
Summary of Sales by Year | VIEW | |
|
|
|
|
|
Suppliers | BASE TABLE | |
|
|
|
|
|
Ten Most Expensive Products | VIEW | |
|
|
|
|
|
Territories | BASE TABLE | |");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DataTestMethod]
|
|
|
|
|
[DataRow(DataAccessProviderType.Odbc)]
|
|
|
|
|
[DataRow(DataAccessProviderType.OleDb)]
|
|
|
|
|
public void Columns(DataAccessProviderType providerType)
|
|
|
|
|
{
|
|
|
|
|
using var connection = Helpers.OpenDatabase(StoreName, providerType);
|
|
|
|
|
var result = Helpers.GetDataReaderContent(
|
|
|
|
|
connection,
|
|
|
|
|
@"SELECT * FROM `INFORMATION_SCHEMA.COLUMNS`
|
|
|
|
|
WHERE TABLE_NAME IN ('Orders', 'Order Details Extended', 'Categories')
|
|
|
|
|
ORDER BY TABLE_NAME,
|
|
|
|
|
COLUMN_NAME");
|
|
|
|
|
|
|
|
|
|
AssertDataReaderContent(result, @"
|
|
|
|
|
`TABLE_NAME` | `COLUMN_NAME` | `ORDINAL_POSITION` | `DATA_TYPE` | `IS_NULLABLE` | `CHARACTER_MAXIMUM_LENGTH` | `NUMERIC_PRECISION` | `NUMERIC_SCALE` | `COLUMN_DEFAULT` | `VALIDATION_RULE` | `VALIDATION_TEXT` | `IDENTITY_SEED` | `IDENTITY_INCREMENT`
|
|
|
|
|
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
|
|
|
|
|
Categories | CategoryID | 0 | counter | False | | | | | | | 9 | 1
|
|
|
|
|
Categories | CategoryName | 1 | varchar | False | 15 | | | | | | |
|
|
|
|
|
Categories | Description | 2 | longchar | True | | | | | | | |
|
|
|
|
|
Categories | Picture | 3 | longbinary | True | | | | | | | |
|
|
|
|
|
Order Details Extended | Discount | 5 | single | False | | | | | | | |
|
|
|
|
|
Order Details Extended | ExtendedPrice | 6 | currency | True | | | | | | | |
|
|
|
|
|
Order Details Extended | OrderID | 0 | integer | False | | | | | | | |
|
|
|
|
|
Order Details Extended | ProductID | 1 | integer | False | | | | | | | |
|
|
|
|
|
Order Details Extended | ProductName | 2 | varchar | False | 40 | | | | | | |
|
|
|
|
|
Order Details Extended | Quantity | 4 | smallint | False | | | | | | | |
|
|
|
|
|
Order Details Extended | UnitPrice | 3 | currency | False | | | | | | | |
|
|
|
|
|
Orders | CustomerID | 1 | char | True | 5 | | | | | | |
|
|
|
|
|
Orders | EmployeeID | 2 | integer | True | | | | | | | |
|
|
|
|
|
Orders | Freight | 7 | decimal | True | | 18 | 2 | 0 | | | |
|
|
|
|
|
Orders | OrderDate | 3 | datetime | True | | | | | | | |
|
|
|
|
|
Orders | OrderID | 0 | counter | False | | | | | | | 11078 | 1
|
|
|
|
|
Orders | RequiredDate | 4 | datetime | True | | | | | | | |
|
|
|
|
|
Orders | ShipAddress | 9 | varchar | True | 60 | | | | | | |
|
|
|
|
|
Orders | ShipCity | 10 | varchar | True | 15 | | | | | | |
|
|
|
|
|
Orders | ShipCountry | 13 | varchar | True | 15 | | | | | | |
|
|
|
|
|
Orders | ShipName | 8 | varchar | True | 40 | | | | | | |
|
|
|
|
|
Orders | ShippedDate | 5 | datetime | True | | | | | | | |
|
|
|
|
|
Orders | ShipPostalCode | 12 | varchar | True | 10 | | | | | | |
|
|
|
|
|
Orders | ShipRegion | 11 | varchar | True | 15 | | | | | | |
|
|
|
|
|
Orders | ShipVia | 6 | integer | True | | | | | | | |");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DataTestMethod]
|
|
|
|
|
[DataRow(DataAccessProviderType.Odbc)]
|
|
|
|
|
[DataRow(DataAccessProviderType.OleDb)]
|
|
|
|
|
public void Indexes(DataAccessProviderType providerType)
|
|
|
|
|
{
|
|
|
|
|
using var connection = Helpers.OpenDatabase(StoreName, providerType);
|
|
|
|
|
var result = Helpers.GetDataReaderContent(
|
|
|
|
|
connection,
|
|
|
|
|
@"SELECT * FROM `INFORMATION_SCHEMA.INDEXES`
|
|
|
|
|
WHERE TABLE_NAME = 'Orders' OR
|
|
|
|
|
TABLE_NAME = 'Order Details'
|
|
|
|
|
ORDER BY TABLE_NAME,
|
|
|
|
|
INDEX_NAME");
|
|
|
|
|
|
|
|
|
|
AssertDataReaderContent(result, @"
|
|
|
|
|
`TABLE_NAME` | `INDEX_NAME` | `INDEX_TYPE` | `IS_NULLABLE` | `IGNORES_NULLS`
|
|
|
|
|
--- | --- | --- | --- | ---
|
|
|
|
|
Order Details | FK_Order_Details_Orders | INDEX | True | False
|
|
|
|
|
Order Details | FK_Order_Details_Products | INDEX | True | False
|
|
|
|
|
Order Details | OrderID | INDEX | True | False
|
|
|
|
|
Order Details | OrdersOrder_Details | INDEX | True | False
|
|
|
|
|
Order Details | PK_Order_Details | PRIMARY | False | False
|
|
|
|
|
Order Details | ProductID | INDEX | True | False
|
|
|
|
|
Order Details | ProductsOrder_Details | INDEX | True | False
|
|
|
|
|
Orders | CustomerID | INDEX | True | False
|
|
|
|
|
Orders | CustomersOrders | INDEX | True | False
|
|
|
|
|
Orders | EmployeeID | INDEX | True | False
|
|
|
|
|
Orders | EmployeesOrders | INDEX | True | False
|
|
|
|
|
Orders | FK_Orders_Customers | INDEX | True | False
|
|
|
|
|
Orders | FK_Orders_Employees | INDEX | True | False
|
|
|
|
|
Orders | FK_Orders_Shippers | INDEX | True | False
|
|
|
|
|
Orders | OrderDate | INDEX | True | False
|
|
|
|
|
Orders | PK_Orders | PRIMARY | False | False
|
|
|
|
|
Orders | ShippedDate | INDEX | True | False
|
|
|
|
|
Orders | ShippedDateDescending | INDEX | True | False
|
|
|
|
|
Orders | ShippersOrders | INDEX | True | False
|
|
|
|
|
Orders | ShipPostalCode | INDEX | True | False");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DataTestMethod]
|
|
|
|
|
[DataRow(DataAccessProviderType.Odbc)]
|
|
|
|
|
[DataRow(DataAccessProviderType.OleDb)]
|
|
|
|
|
public void IndexColumns(DataAccessProviderType providerType)
|
|
|
|
|
{
|
|
|
|
|
using var connection = Helpers.OpenDatabase(StoreName, providerType);
|
|
|
|
|
var result = Helpers.GetDataReaderContent(
|
|
|
|
|
connection,
|
|
|
|
|
@"SELECT * FROM `INFORMATION_SCHEMA.INDEX_COLUMNS`
|
|
|
|
|
WHERE TABLE_NAME = 'Orders' OR
|
|
|
|
|
TABLE_NAME = 'Order Details'
|
|
|
|
|
ORDER BY TABLE_NAME,
|
|
|
|
|
INDEX_NAME,
|
|
|
|
|
ORDINAL_POSITION");
|
|
|
|
|
|
|
|
|
|
AssertDataReaderContent(result, @"
|
|
|
|
|
`TABLE_NAME` | `INDEX_NAME` | `ORDINAL_POSITION` | `COLUMN_NAME` | `IS_DESCENDING`
|
|
|
|
|
--- | --- | --- | --- | ---
|
|
|
|
|
Order Details | FK_Order_Details_Orders | 0 | OrderID | False
|
|
|
|
|
Order Details | FK_Order_Details_Products | 0 | ProductID | False
|
|
|
|
|
Order Details | OrderID | 0 | OrderID | False
|
|
|
|
|
Order Details | OrdersOrder_Details | 0 | OrderID | False
|
|
|
|
|
Order Details | PK_Order_Details | 0 | OrderID | False
|
|
|
|
|
Order Details | PK_Order_Details | 1 | ProductID | False
|
|
|
|
|
Order Details | ProductID | 0 | ProductID | False
|
|
|
|
|
Order Details | ProductsOrder_Details | 0 | ProductID | False
|
|
|
|
|
Orders | CustomerID | 0 | CustomerID | False
|
|
|
|
|
Orders | CustomersOrders | 0 | CustomerID | False
|
|
|
|
|
Orders | EmployeeID | 0 | EmployeeID | False
|
|
|
|
|
Orders | EmployeesOrders | 0 | EmployeeID | False
|
|
|
|
|
Orders | FK_Orders_Customers | 0 | CustomerID | False
|
|
|
|
|
Orders | FK_Orders_Employees | 0 | EmployeeID | False
|
|
|
|
|
Orders | FK_Orders_Shippers | 0 | ShipVia | False
|
|
|
|
|
Orders | OrderDate | 0 | OrderDate | False
|
|
|
|
|
Orders | PK_Orders | 0 | OrderID | False
|
|
|
|
|
Orders | ShippedDate | 0 | ShippedDate | False
|
|
|
|
|
Orders | ShippedDateDescending | 0 | ShippedDate | True
|
|
|
|
|
Orders | ShippersOrders | 0 | ShipVia | False
|
|
|
|
|
Orders | ShipPostalCode | 0 | ShipPostalCode | False");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DataTestMethod]
|
|
|
|
|
[DataRow(DataAccessProviderType.Odbc)]
|
|
|
|
|
[DataRow(DataAccessProviderType.OleDb)]
|
|
|
|
|
public void Relations(DataAccessProviderType providerType)
|
|
|
|
|
{
|
|
|
|
|
using var connection = Helpers.OpenDatabase(StoreName, providerType);
|
|
|
|
|
var result = Helpers.GetDataReaderContent(
|
|
|
|
|
connection,
|
|
|
|
|
@"SELECT * FROM `INFORMATION_SCHEMA.RELATIONS`
|
|
|
|
|
WHERE PRINCIPAL_TABLE_NAME = 'Orders' AND
|
|
|
|
|
REFERENCING_TABLE_NAME = 'Order Details'
|
|
|
|
|
ORDER BY RELATION_NAME");
|
|
|
|
|
|
|
|
|
|
AssertDataReaderContent(result, @"
|
|
|
|
|
`RELATION_NAME` | `REFERENCING_TABLE_NAME` | `PRINCIPAL_TABLE_NAME` | `RELATION_TYPE` | `ON_DELETE` | `ON_UPDATE` | `IS_ENFORCED` | `IS_INHERITED`
|
|
|
|
|
--- | --- | --- | --- | --- | --- | --- | ---
|
|
|
|
|
FK_Order_Details_Orders | Order Details | Orders | MANY | NO ACTION | NO ACTION | True | True");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DataTestMethod]
|
|
|
|
|
[DataRow(DataAccessProviderType.Odbc)]
|
|
|
|
|
[DataRow(DataAccessProviderType.OleDb)]
|
|
|
|
|
public void RelationColumns(DataAccessProviderType providerType)
|
|
|
|
|
{
|
|
|
|
|
using var connection = Helpers.OpenDatabase(StoreName, providerType);
|
|
|
|
|
var result = Helpers.GetDataReaderContent(
|
|
|
|
|
connection,
|
|
|
|
|
@"SELECT * FROM `INFORMATION_SCHEMA.RELATION_COLUMNS`
|
|
|
|
|
WHERE RELATION_NAME = 'FK_Order_Details_Orders'
|
|
|
|
|
ORDER BY RELATION_NAME, REFERENCING_COLUMN_NAME, PRINCIPAL_COLUMN_NAME");
|
|
|
|
|
|
|
|
|
|
AssertDataReaderContent(result, @"
|
|
|
|
|
`RELATION_NAME` | `REFERENCING_COLUMN_NAME` | `PRINCIPAL_COLUMN_NAME` | `ORDINAL_POSITION`
|
|
|
|
|
--- | --- | --- | ---
|
|
|
|
|
FK_Order_Details_Orders | OrderID | OrderID | 1");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DataTestMethod]
|
|
|
|
|
[DataRow(DataAccessProviderType.Odbc)]
|
|
|
|
|
[DataRow(DataAccessProviderType.OleDb)]
|
|
|
|
|
public void CheckConstraints(DataAccessProviderType providerType)
|
|
|
|
|
{
|
|
|
|
|
using var connection = Helpers.OpenDatabase(StoreName, providerType);
|
|
|
|
|
var result = Helpers.GetDataReaderContent(
|
|
|
|
|
connection,
|
|
|
|
|
@"SELECT * FROM `INFORMATION_SCHEMA.CHECK_CONSTRAINTS`
|
|
|
|
|
ORDER BY TABLE_NAME, CONSTRAINT_NAME");
|
|
|
|
|
|
|
|
|
|
AssertDataReaderContent(result, $@"
|
|
|
|
|
`TABLE_NAME` | `CONSTRAINT_NAME` | `CHECK_CLAUSE`
|
|
|
|
|
--- | --- | ---
|
|
|
|
|
{JetConnection.DefaultDualTableName} | SingleRecord | (SELECT COUNT(*) FROM [{JetConnection.DefaultDualTableName}]) = 1
|
|
|
|
|
Employees | CK_BirthDate | [BirthDate] < NOW()
|
|
|
|
|
Order Details | CK_Discount | [Discount] >= 0 and ([Discount] <= 1)
|
|
|
|
|
Order Details | CK_Quantity | [Quantity] > 0
|
|
|
|
|
Order Details | CK_UnitPrice | [UnitPrice] >= 0
|
|
|
|
|
Products | CK_Products_UnitPrice | [UnitPrice] >= 0
|
|
|
|
|
Products | CK_ReorderLevel | [ReorderLevel] >= 0
|
|
|
|
|
Products | CK_UnitsInStock | [UnitsInStock] >= 0
|
|
|
|
|
Products | CK_UnitsOnOrder | [UnitsOnOrder] >= 0");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|