/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.server.test.it.keyupdate; import com.foundationdb.qp.row.Row; import com.foundationdb.qp.rowtype.RowType; import com.foundationdb.server.api.dml.scan.NewRow; import com.foundationdb.server.error.ErrorCode; import com.foundationdb.server.error.InvalidOperationException; import com.foundationdb.server.rowdata.RowDef; import org.junit.Test; import java.util.List; import static com.foundationdb.server.test.it.keyupdate.Schema.*; import static org.junit.Assert.*; // Like KeyUpdateIT, but with multi-column keys public class MultiColumnKeyUpdateIT extends KeyUpdateBase { @Test public void testItemFKUpdate() throws Exception { // Set item.oid1 = 0 for item 1222 KeyUpdateRow originalItem = testStore.find(new HKey(vendorRT, 1L, 1L, customerRT, 12L, 12L, orderRT, 122L, 122L, itemRT, 1222L, 1222L)); KeyUpdateRow updatedItem = updateRow(originalItem, i_oid1, 0L, null); startMonitoringHKeyPropagation(); dbUpdate(originalItem, updatedItem); checkHKeyPropagation(0, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbUpdate(updatedItem, originalItem); checkHKeyPropagation(0, 0); checkDB(); checkInitialState(); } @Test public void testItemPKUpdate() throws Exception { // Set item.iid = 0 for item 1222 KeyUpdateRow order = testStore.find(new HKey(vendorRT, 1L, 1L, customerRT, 12L, 12L, orderRT, 122L, 122L)); KeyUpdateRow originalItem = testStore.find(new HKey(vendorRT, 1L, 1L, customerRT, 12L, 12L, orderRT, 122L, 122L, itemRT, 1222L, 1222L)); assertNotNull(order); KeyUpdateRow updatedItem = updateRow(originalItem, i_iid2, 0L, order); startMonitoringHKeyPropagation(); dbUpdate(originalItem, updatedItem); checkHKeyPropagation(0, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbUpdate(updatedItem, originalItem); checkHKeyPropagation(0, 0); checkDB(); checkInitialState(); } @Test public void testItemPKUpdateCreatingDuplicate() throws Exception { // Set item.iid = 1223 for item 1222 KeyUpdateRow order = testStore.find(new HKey(vendorRT, 1L, 1L, customerRT, 12L, 12L, orderRT, 122L, 122L)); KeyUpdateRow originalItem = testStore.find(new HKey(vendorRT, 1L, 1L, customerRT, 12L, 12L, orderRT, 122L, 122L, itemRT, 1222L, 1222L)); assertNotNull(order); KeyUpdateRow updatedItem = updateRow(originalItem, i_iid1, 1223L, i_iid2, 1223L, order); try { dbUpdate(originalItem, updatedItem); fail(); } catch (InvalidOperationException e) { assertEquals(ErrorCode.DUPLICATE_KEY, e.getCode()); } checkDB(); checkInitialState(); } @Test public void testOrderFKUpdate() throws Exception { // Set order.cid = 0 for order 222 KeyUpdateRow customer = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L)); KeyUpdateRow originalOrder = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, 222L, 222L)); KeyUpdateRow updatedOrder = updateRow(originalOrder, o_cid1, 0L, o_cid2, 0L, null); // Propagate change to order 222's items to reflect db state for (long iid = 2221; iid <= 2223; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, 222L, 222L, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, updatedOrder)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } startMonitoringHKeyPropagation(); dbUpdate(originalOrder, updatedOrder); checkHKeyPropagation(2, 6); checkDB(); // Revert change for (long iid = 2221; iid <= 2223; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, null, null, customerRT, 0L, 0L, orderRT, 222L, 222L, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, originalOrder, customer)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } startMonitoringHKeyPropagation(); dbUpdate(updatedOrder, originalOrder); checkHKeyPropagation(2, 6); checkDB(); checkInitialState(); } @Test public void testOrderPKUpdate() throws Exception { // Set order.oid = 0 for order 222 KeyUpdateRow customer = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L)); KeyUpdateRow originalOrder = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, 222L, 222L)); KeyUpdateRow udpatedOrder = updateRow(originalOrder, o_oid1, 0L, o_oid2, 0L, customer); // Propagate change to order 222's items to reflect db state for (long iid = 2221; iid <= 2223; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, 222L, 222L, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, null)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } startMonitoringHKeyPropagation(); dbUpdate(originalOrder, udpatedOrder); checkHKeyPropagation(2, 3); // 3: 3 items become orphans, no items are adopted orphans. checkDB(); // Revert change for (long iid = 2221; iid <= 2223; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, null, null, customerRT,null, null, orderRT, 222L, 222L, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, originalOrder, customer)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } startMonitoringHKeyPropagation(); dbUpdate(udpatedOrder, originalOrder); checkHKeyPropagation(2, 3); checkDB(); checkInitialState(); } @Test public void testOrderPKUpdateCreatingDuplicate() throws Exception { // Set order.oid = 221 for order 222 KeyUpdateRow customer = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L)); KeyUpdateRow originalOrder = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, 222L, 222L)); assertNotNull(customer); KeyUpdateRow updatedOrder = updateRow(originalOrder, o_oid1, 221L, o_oid2, 221L, customer); try { dbUpdate(originalOrder, updatedOrder); fail(); } catch (InvalidOperationException e) { assertEquals(ErrorCode.DUPLICATE_KEY, e.getCode()); } checkDB(); } @Test public void testCustomerFKUpdate() throws Exception { // Set customer.vid = 0 for customer 13 KeyUpdateRow originalCustomer = testStore.find(new HKey(vendorRT, 1L, 1L, customerRT, 13L, 13L)); KeyUpdateRow udpatedCustomer = updateRow(originalCustomer, c_vid1, 0L, c_vid2, 0L, null); // Propagate change to customer 13s descendents to reflect db state for (long oid = 131; oid <= 133; oid++) { KeyUpdateRow oldOrderRow = testStore.find(new HKey(vendorRT, 1L, 1L, customerRT, 13L, 13L, orderRT, oid, oid)); KeyUpdateRow newOrderRow = copyRow(oldOrderRow); newOrderRow.hKey(hKey(newOrderRow, udpatedCustomer)); testStore.deleteTestRow(oldOrderRow); testStore.writeTestRow(newOrderRow); for (long iid = oid * 10 + 1; iid <= oid * 10 + 3; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, 1L, 1L, customerRT, 13L, 13L, orderRT, oid, oid, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, newOrderRow, udpatedCustomer)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } } startMonitoringHKeyPropagation(); dbUpdate(originalCustomer, udpatedCustomer); checkHKeyPropagation(2, 24); // 3 orders, 3 items per order, delete/reinsert each checkDB(); // Revert change for (long oid = 131; oid <= 133; oid++) { KeyUpdateRow oldOrderRow = testStore.find(new HKey(vendorRT, 0L, 0L, customerRT, 13L, 13L, orderRT, oid, oid)); KeyUpdateRow newOrderRow = copyRow(oldOrderRow); newOrderRow.hKey(hKey(newOrderRow, originalCustomer)); testStore.deleteTestRow(oldOrderRow); testStore.writeTestRow(newOrderRow); for (long iid = oid * 10 + 1; iid <= oid * 10 + 3; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, 0L, 0L, customerRT, 13L, 13L, orderRT, oid, oid, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, newOrderRow, originalCustomer)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } } startMonitoringHKeyPropagation(); dbUpdate(udpatedCustomer, originalCustomer); checkHKeyPropagation(2, 24); checkDB(); checkInitialState(); } @Test public void testCustomerPKUpdate() throws Exception { // Set customer.cid = 0 for customer 22 KeyUpdateRow originalCustomer = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L)); KeyUpdateRow updatedCustomer = updateRow(originalCustomer, c_cid2, 23L, null); // Propagate change to customer 22's orders and items to reflect db state for (long oid = 221; oid <= 223; oid++) { KeyUpdateRow oldOrderRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, oid, oid)); KeyUpdateRow newOrderRow = copyRow(oldOrderRow); newOrderRow.hKey(hKey(newOrderRow, null)); testStore.deleteTestRow(oldOrderRow); testStore.writeTestRow(newOrderRow); for (long iid = oid * 10 + 1; iid <= oid * 10 + 3; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, oid, oid, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, newOrderRow)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } } startMonitoringHKeyPropagation(); dbUpdate(originalCustomer, updatedCustomer); checkHKeyPropagation(2, 12); // 3 orders, 3 items per order, delete, but no reinsert - there is no customer 0 checkDB(); // Revert change for (long oid = 221; oid <= 223; oid++) { KeyUpdateRow oldOrderRow = testStore.find(new HKey(vendorRT, null, null, customerRT, 22L, 22L, orderRT, oid, oid)); KeyUpdateRow newOrderRow = copyRow(oldOrderRow); newOrderRow.hKey(hKey(newOrderRow, originalCustomer)); testStore.deleteTestRow(oldOrderRow); testStore.writeTestRow(newOrderRow); for (long iid = oid * 10 + 1; iid <= oid * 10 + 3; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, null, null, customerRT, 22L, 22L, orderRT, oid, oid, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, newOrderRow, originalCustomer)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } } startMonitoringHKeyPropagation(); dbUpdate(updatedCustomer, originalCustomer); checkHKeyPropagation(2, 12); checkDB(); checkInitialState(); } @Test public void testCustomerPKUpdateCreatingDuplicate() throws Exception { // Set customer.cid = 11 for customer 23 KeyUpdateRow originalCustomer = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 23L, 23L)); KeyUpdateRow updatedCustomer = updateRow(originalCustomer, c_cid1, 11L, c_cid2, 11L, null); try { dbUpdate(originalCustomer, updatedCustomer); fail(); } catch (InvalidOperationException e) { assertEquals(ErrorCode.DUPLICATE_KEY, e.getCode()); } checkDB(); } @Test public void testVendorPKUpdate() throws Exception { // Set vendor.vid = 0 for vendor 1 KeyUpdateRow originalVendor = testStore.find(new HKey(vendorRT, 1L, 1L)); KeyUpdateRow updatedVendor = updateRow(originalVendor, v_vid1, 0L, null); startMonitoringHKeyPropagation(); dbUpdate(originalVendor, updatedVendor); checkHKeyPropagation(2, 0); // customer has vid, isn't affected by vendor update checkDB(); // Revert change startMonitoringHKeyPropagation(); dbUpdate(updatedVendor, originalVendor); checkHKeyPropagation(2, 0); checkDB(); checkInitialState(); } @Test public void testVendorPKUpdateCreatingDuplicate() throws Exception { // Set vendor.vid = 2 for vendor 1 KeyUpdateRow originalVendorRow = testStore.find(new HKey(vendorRT, 1L, 1L)); KeyUpdateRow updatedVendorRow = updateRow(originalVendorRow, v_vid1, 2L, v_vid2, 2L, null); try { dbUpdate(originalVendorRow, updatedVendorRow); fail(); } catch (InvalidOperationException e) { assertEquals(ErrorCode.DUPLICATE_KEY, e.getCode()); } checkDB(); } @Test public void testItemDelete() throws Exception { KeyUpdateRow itemRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, 222L, 222L, itemRT, 2222L, 2222L)); startMonitoringHKeyPropagation(); dbDelete(itemRow); checkHKeyPropagation(0, 0); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbInsert(itemRow); checkHKeyPropagation(0, 0); checkDB(); checkInitialState(); } @Test public void testOrderDelete() throws Exception { KeyUpdateRow customerRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L)); KeyUpdateRow orderRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, 222L, 222L)); // Propagate change to order 222's items to reflect db state for (long iid = 2221; iid <= 2223; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, 222L, 222L, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, null)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } startMonitoringHKeyPropagation(); dbDelete(orderRow); checkHKeyPropagation(1, 3); checkDB(); // Revert change for (long iid = 2221; iid <= 2223; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, null, null, customerRT, null, null, orderRT, 222L, 222L, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, orderRow, customerRow)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } startMonitoringHKeyPropagation(); dbInsert(orderRow); checkHKeyPropagation(1, 3); checkDB(); checkInitialState(); } @Test public void testCustomerDelete() throws Exception { KeyUpdateRow customerRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L)); // Propagate change to customer's descendents to reflect db state for (long oid = 221; oid <= 223; oid++) { KeyUpdateRow oldOrderRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, oid, oid)); KeyUpdateRow newOrderRow = copyRow(oldOrderRow); newOrderRow.hKey(hKey(newOrderRow, null)); testStore.deleteTestRow(oldOrderRow); testStore.writeTestRow(newOrderRow); for (long iid = oid * 10 + 1; iid <= oid * 10 + 3; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, 2L, 2L, customerRT, 22L, 22L, orderRT, oid, oid, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, newOrderRow)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } } startMonitoringHKeyPropagation(); dbDelete(customerRow); // 12; 3 orders, with 3 items each checkHKeyPropagation(1, 12); checkDB(); // Revert change for (long oid = 221; oid <= 223; oid++) { KeyUpdateRow oldOrderRow = testStore.find(new HKey(vendorRT, null, null, customerRT, 22L, 22L, orderRT, oid, oid)); KeyUpdateRow newOrderRow = copyRow(oldOrderRow); newOrderRow.hKey(hKey(newOrderRow, customerRow)); testStore.deleteTestRow(oldOrderRow); testStore.writeTestRow(newOrderRow); for (long iid = oid * 10 + 1; iid <= oid * 10 + 3; iid++) { KeyUpdateRow oldItemRow = testStore.find(new HKey(vendorRT, null, null, customerRT, 22L, 22L, orderRT, oid, oid, itemRT, iid, iid)); KeyUpdateRow newItemRow = copyRow(oldItemRow); newItemRow.hKey(hKey(newItemRow, newOrderRow, customerRow)); testStore.deleteTestRow(oldItemRow); testStore.writeTestRow(newItemRow); } } startMonitoringHKeyPropagation(); dbInsert(customerRow); checkHKeyPropagation(1, 12); checkDB(); checkInitialState(); } @Test public void testVendorDelete() throws Exception { KeyUpdateRow vendorRow = testStore.find(new HKey(vendorRT, 1L, 1L)); startMonitoringHKeyPropagation(); dbDelete(vendorRow); // TODO: Why not apply the PDG optimization on inserts and deletes? checkHKeyPropagation(1, 39); checkDB(); // Revert change startMonitoringHKeyPropagation(); dbInsert(vendorRow); checkHKeyPropagation(1, 39); checkDB(); checkInitialState(); } @Override protected void createSchema() throws InvalidOperationException { // vendor vendorId = createTable("coi", "vendor", "vid1 bigint not null", "vx bigint", "vid2 bigint not null", "primary key(vid1, vid2)"); v_vid1 = 0; v_vid2 = 2; v_vx = 1; // customer customerId = createTable("coi", "customer", "vid1 bigint", "cid2 bigint not null", "vid2 bigint", "cx bigint", "cid1 bigint not null", "primary key(cid1, cid2)", "grouping foreign key (vid1, vid2) references vendor(vid1, vid2)"); c_cid1 = 4; c_cid2 = 1; c_vid1 = 0; c_vid2 = 2; c_cx = 3; // order orderId = createTable("coi", "order", "cid1 bigint", "cid2 bigint", "oid2 bigint not null", "oid1 bigint not null", "ox bigint", "priority bigint", "when bigint", "primary key(oid1, oid2)", "unique(when)", "grouping foreign key (cid1, cid2) references customer(cid1, cid2)"); createIndex("coi", "order", "priority", "priority"); o_oid1 = 3; o_oid2 = 2; o_cid1 = 0; o_cid2 = 1; o_ox = 4; o_priority = 5; o_when = 6; // item itemId = createTable("coi", "item", "ix bigint", "oid1 bigint", "oid2 bigint", "iid1 bigint not null", "iid2 bigint not null", "primary key(iid1, iid2)", "grouping foreign key (oid1, oid2) references \"order\"(oid1, oid2)"); i_iid1 = 3; i_iid2 = 4; i_oid1 = 1; i_oid2 = 2; i_ix = 0; // group vendorRT = getRowType(vendorId); customerRT = getRowType(customerId); orderRT = getRowType(orderId); itemRT = getRowType(itemId); group = customerRT.table().getGroup(); } @Override protected List<List<Object>> vendorPKIndex(List<TreeRecord> records) { return indexFromRecords(records, vendorRT, v_vid1, v_vid2); } @Override protected List<List<Object>> customerPKIndex(List<TreeRecord> records) { return indexFromRecords(records, customerRT, c_cid1, c_cid2, c_vid1, c_vid2); } @Override protected List<List<Object>> orderPKIndex(List<TreeRecord> records) { return indexFromRecords(records, orderRT, o_oid1, o_oid2, HKeyElement.from(1), HKeyElement.from(2), o_cid1, o_cid2); } @Override protected List<List<Object>> itemPKIndex(List<TreeRecord> records) { return indexFromRecords(records, itemRT, i_iid1, i_iid2, HKeyElement.from(1), HKeyElement.from(2), HKeyElement.from(4), HKeyElement.from(5), i_oid1, i_oid2); } @Override protected List<List<Object>> orderPriorityIndex(List<TreeRecord> records) { return indexFromRecords(records, orderRT, o_priority, HKeyElement.from(1), HKeyElement.from(2), o_cid1, o_cid2, o_oid1, o_oid2); } @Override protected List<List<Object>> orderWhenIndex(List<TreeRecord> records) { return indexFromRecords(records, orderRT, o_when, HKeyElement.from(1), HKeyElement.from(2), o_cid1, o_cid2, o_oid1, o_oid2); } // vendorRow, customerRow, orderRow and itemRow: The formatting of populateTables above is copied from // KeyUpdateIT. Because of the duplicated column values and weird column orders, that formatting doesn't // really work here. The functions below translate the rows, formatted as for the KeyUpdateIT schema, // and generates the correct rows for this test. @Override protected void populateTables() throws Exception { // non-key vendor fields // vx = vid * 100 // non-key customer fields // cx = cid * 100 // non-key order fields // ox = oid * 100 // priority = 8[1-3] // when = unique, start counting at 9001 // non-key item fields // ix = iid * 100 KeyUpdateRow customer; KeyUpdateRow order; // HKey reversed, value // Vendor 1 dbInsert( vendorRow(1, 100)); // dbInsert(customer = customerRow(11, 1, 1100)); dbInsert(order = orderRow(customer, 111, 11, 11100, 81, 9001)); dbInsert( itemRow(customer, order, 1111, 111, 111100)); dbInsert( itemRow(customer, order, 1112, 111, 111200)); dbInsert( itemRow(customer, order, 1113, 111, 111300)); dbInsert(order = orderRow(customer, 112, 11, 11200, 83, 9002)); dbInsert( itemRow(customer, order, 1121, 112, 112100)); dbInsert( itemRow(customer, order, 1122, 112, 112200)); dbInsert( itemRow(customer, order, 1123, 112, 112300)); dbInsert(order = orderRow(customer, 113, 11, 11300, 81, 9003)); dbInsert( itemRow(customer, order, 1131, 113, 113100)); dbInsert( itemRow(customer, order, 1132, 113, 113200)); dbInsert( itemRow(customer, order, 1133, 113, 113300)); dbInsert(customer = customerRow(12, 1, 1200)); dbInsert(order = orderRow(customer, 121, 12, 12100, 83, 9004)); dbInsert( itemRow(customer, order, 1211, 121, 121100)); dbInsert( itemRow(customer, order, 1212, 121, 121200)); dbInsert( itemRow(customer, order, 1213, 121, 121300)); dbInsert(order = orderRow(customer, 122, 12, 12200, 81, 9005)); dbInsert( itemRow(customer, order, 1221, 122, 122100)); dbInsert( itemRow(customer, order, 1222, 122, 122200)); dbInsert( itemRow(customer, order, 1223, 122, 122300)); dbInsert(order = orderRow(customer, 123, 12, 12300, 82, 9006)); dbInsert( itemRow(customer, order, 1231, 123, 123100)); dbInsert( itemRow(customer, order, 1232, 123, 123200)); dbInsert( itemRow(customer, order, 1233, 123, 123300)); dbInsert(customer = customerRow(13, 1, 1300)); dbInsert(order = orderRow(customer, 131, 13, 13100, 82, 9007)); dbInsert( itemRow(customer, order, 1311, 131, 131100)); dbInsert( itemRow(customer, order, 1312, 131, 131200)); dbInsert( itemRow(customer, order, 1313, 131, 131300)); dbInsert(order = orderRow(customer, 132, 13, 13200, 83, 9008)); dbInsert( itemRow(customer, order, 1321, 132, 132100)); dbInsert( itemRow(customer, order, 1322, 132, 132200)); dbInsert( itemRow(customer, order, 1323, 132, 132300)); dbInsert(order = orderRow(customer, 133, 13, 13300, 81, 9009)); dbInsert( itemRow(customer, order, 1331, 133, 133100)); dbInsert( itemRow(customer, order, 1332, 133, 133200)); dbInsert( itemRow(customer, order, 1333, 133, 133300)); // // Vendor 2 dbInsert( vendorRow(2, 200)); // dbInsert(customer = customerRow(21, 2, 2100)); dbInsert(order = orderRow(customer, 211, 21, 21100, 81, 9010)); dbInsert( itemRow(customer, order, 2111, 211, 211100)); dbInsert( itemRow(customer, order, 2112, 211, 211200)); dbInsert( itemRow(customer, order, 2113, 211, 211300)); dbInsert(order = orderRow(customer, 212, 21, 21200, 83, 9011)); dbInsert( itemRow(customer, order, 2121, 212, 212100)); dbInsert( itemRow(customer, order, 2122, 212, 212200)); dbInsert( itemRow(customer, order, 2123, 212, 212300)); dbInsert(order = orderRow(customer, 213, 21, 21300, 82, 9012)); dbInsert( itemRow(customer, order, 2131, 213, 213100)); dbInsert( itemRow(customer, order, 2132, 213, 213200)); dbInsert( itemRow(customer, order, 2133, 213, 213300)); dbInsert(customer = customerRow(22, 2, 2200)); dbInsert(order = orderRow(customer, 221, 22, 22100, 82, 9013)); dbInsert( itemRow(customer, order, 2211, 221, 221100)); dbInsert( itemRow(customer, order, 2212, 221, 221200)); dbInsert( itemRow(customer, order, 2213, 221, 221300)); dbInsert(order = orderRow(customer, 222, 22, 22200, 82, 9014)); dbInsert( itemRow(customer, order, 2221, 222, 222100)); dbInsert( itemRow(customer, order, 2222, 222, 222200)); dbInsert( itemRow(customer, order, 2223, 222, 222300)); dbInsert(order = orderRow(customer, 223, 22, 22300, 81, 9015)); dbInsert( itemRow(customer, order, 2231, 223, 223100)); dbInsert( itemRow(customer, order, 2232, 223, 223200)); dbInsert( itemRow(customer, order, 2233, 223, 223300)); dbInsert(customer = customerRow(23, 2, 2300)); dbInsert(order = orderRow(customer, 231, 23, 23100, 82, 9016)); dbInsert( itemRow(customer, order, 2311, 231, 231100)); dbInsert( itemRow(customer, order, 2312, 231, 231200)); dbInsert( itemRow(customer, order, 2313, 231, 231300)); dbInsert(order = orderRow(customer, 232, 23, 23200, 83, 9017)); dbInsert( itemRow(customer, order, 2321, 232, 232100)); dbInsert( itemRow(customer, order, 2322, 232, 232200)); dbInsert( itemRow(customer, order, 2323, 232, 232300)); dbInsert(order = orderRow(customer, 233, 23, 23300, 81, 9018)); dbInsert( itemRow(customer, order, 2331, 233, 233100)); dbInsert( itemRow(customer, order, 2332, 233, 233200)); dbInsert( itemRow(customer, order, 2333, 233, 233300)); } private KeyUpdateRow vendorRow(long vid, long vx) { KeyUpdateRow vendor = createTestRow(vendorRT, vid, vx, vid); vendor.hKey(new HKey(vendorRT, vid, vid)); return vendor; } private KeyUpdateRow customerRow(long cid, long vid, long cx) { KeyUpdateRow customer = createTestRow(customerRT, vid, cid, vid, cx, cid); customer.hKey(new HKey(vendorRT, vid, vid, customerRT, cid, cid)); return customer; } private KeyUpdateRow orderRow(KeyUpdateRow customer, long oid, long cid, long ox, long priority, long when) { KeyUpdateRow order = createTestRow(orderRT, cid, cid, oid, oid, ox, priority, when); order.hKey(new HKey(vendorRT, customer.value(c_vid1).getInt64(), customer.value(c_vid2).getInt64(), customerRT, cid, cid, orderRT, oid, oid)); order.parent(customer); return order; } private KeyUpdateRow itemRow(KeyUpdateRow customer, KeyUpdateRow order, long iid, long oid, long ix) { KeyUpdateRow item = createTestRow(itemRT, ix, oid, oid, iid, iid); item.hKey(new HKey(vendorRT, customer.value(c_vid1).getInt64(), customer.value(c_vid2).getInt64(), customerRT, order.value(o_cid1).getInt64(), order.value(o_cid2).getInt64(), orderRT, oid, oid, itemRT, iid, iid)); item.parent(order); return item; } @Override protected HKey hKey(KeyUpdateRow row) { HKey hKey = null; RowType rowType = row.rowType(); if (rowType == vendorRT) { hKey = new HKey(vendorRT, row.value(v_vid1).getInt64(), row.value(v_vid2).getInt64()); } else if (rowType == customerRT) { hKey = new HKey(vendorRT, row.value(c_vid1).getInt64(), row.value(c_vid2).getInt64(), customerRT, row.value(c_cid1).getInt64(), row.value(c_cid2).getInt64()); } else if (rowType == orderRT) { assertNotNull(row.parent()); hKey = new HKey(vendorRT, row.parent().value(c_vid1).getInt64(), row.parent().value(c_vid2).getInt64(), customerRT, row.value(o_cid1).getInt64(), row.value(o_cid2).getInt64(), orderRT, row.value(o_oid1).getInt64(), row.value(o_oid2).getInt64()); } else if (rowType == itemRT) { assertNotNull(row.parent()); assertNotNull(row.parent().parent()); hKey = new HKey(vendorRT, row.parent().parent().value(c_vid1).getInt64(), row.parent().parent().value(c_vid2).getInt64(), customerRT, row.parent().value(o_cid1).getInt64(), row.parent().value(o_cid2).getInt64(), orderRT, row.value(i_oid1).getInt64(), row.value(i_oid2).getInt64(), itemRT, row.value(i_iid1).getInt64(), row.value(i_iid2).getInt64()); } else { fail(); } return hKey; } @Override protected boolean checkChildPKs() { return true; } @Override protected HKey hKey(KeyUpdateRow row, KeyUpdateRow parent, KeyUpdateRow grandparent) { HKey hKey = null; RowType rowType = row.rowType(); if (rowType == vendorRT) { hKey = new HKey(vendorRT, row.value(v_vid1).getInt64(), row.value(v_vid2).getInt64()); } else if (rowType == customerRT) { hKey = new HKey(vendorRT, row.value(c_vid1).getInt64(), row.value(c_vid2).getInt64(), customerRT, row.value(c_cid1).getInt64(), row.value(c_cid2).getInt64()); } else if (rowType == orderRT) { hKey = new HKey(vendorRT, parent == null ? null : parent.value(c_vid1).getInt64(), parent == null ? null : parent.value(c_vid2).getInt64(), customerRT, row.value(o_cid1).getInt64(), row.value(o_cid2).getInt64(), orderRT, row.value(o_oid1).getInt64(), row.value(o_oid2).getInt64()); } else if (rowType == itemRT) { hKey = new HKey(vendorRT, grandparent == null ? null : grandparent.value(c_vid1).getInt64(), grandparent == null ? null : grandparent.value(c_vid2).getInt64(), customerRT, parent == null ? null : parent.value(o_cid1).getInt64(), parent == null ? null : parent.value(o_cid2).getInt64(), orderRT, row.value(i_oid1).getInt64(), row.value(i_oid2).getInt64(), itemRT, row.value(i_iid1).getInt64(), row.value(i_iid2).getInt64()); } else { fail(); } row.parent(parent); return hKey; } @Override protected void checkInitialState(Row row) { RowType rowType = row.rowType(); if (rowType == vendorRT) { assertEquals(row.value(v_vx).getInt64(), row.value(v_vid1).getInt64() * 100); assertEquals(row.value(v_vx).getInt64(), row.value(v_vid2).getInt64() * 100); } else if (rowType == customerRT) { assertEquals(row.value(c_cx).getInt64(), row.value(c_cid1).getInt64() * 100); assertEquals(row.value(c_cx).getInt64(), row.value(c_cid2).getInt64() * 100); } else if (rowType == orderRT) { assertEquals(row.value(o_cid1).getInt64(), row.value(o_oid1).getInt64()/ 10); assertEquals(row.value(o_cid2).getInt64(), row.value(o_oid2).getInt64() / 10); assertEquals(row.value(o_ox).getInt64(), row.value(o_oid1).getInt64() * 100); assertEquals(row.value(o_ox).getInt64(), row.value(o_oid2).getInt64() * 100); } else if (rowType == itemRT) { assertEquals(row.value(i_oid1).getInt64(), row.value(i_iid1).getInt64() / 10); assertEquals(row.value(i_oid2).getInt64(), row.value(i_iid2).getInt64() / 10); assertEquals(row.value(i_ix).getInt64(), row.value(i_iid1).getInt64() * 100); assertEquals(row.value(i_ix).getInt64(), row.value(i_iid2).getInt64() * 100); } else { fail(); } } @Override protected void confirmColumns() { confirmColumn(vendorRT, v_vid1, "vid1"); confirmColumn(vendorRT, v_vid2, "vid2"); confirmColumn(vendorRT, v_vx, "vx"); confirmColumn(customerRT, c_cid1, "cid1"); confirmColumn(customerRT, c_cid2, "cid2"); confirmColumn(customerRT, c_vid1, "vid1"); confirmColumn(customerRT, c_vid2, "vid2"); confirmColumn(customerRT, c_cx, "cx"); confirmColumn(orderRT, o_oid1, "oid1"); confirmColumn(orderRT, o_oid2, "oid2"); confirmColumn(orderRT, o_cid1, "cid1"); confirmColumn(orderRT, o_cid2, "cid2"); confirmColumn(orderRT, o_ox, "ox"); confirmColumn(orderRT, o_priority, "priority"); confirmColumn(orderRT, o_when, "when"); confirmColumn(itemRT, i_iid1, "iid1"); confirmColumn(itemRT, i_iid2, "iid2"); confirmColumn(itemRT, i_oid1, "oid1"); confirmColumn(itemRT, i_oid2, "oid2"); confirmColumn(itemRT, i_ix, "ix"); } }