Beispiel #1
0
 public void Dispose()
 {
     CreatedTables.Clear();
     DroppedTables.Clear();
     CreatedTables = null;
     DroppedTables = null;
 }
        public async Task <TableName> CreateTable()
        {
            var tableName = new TableName(ProjectName.ProjectId, InstanceName.InstanceId, Guid.NewGuid().ToString());

            CreatedTables.Add(tableName);
            await TableAdminClient.CreateTableAsync(
                new InstanceName(tableName.ProjectId, tableName.InstanceId),
                tableName.TableId,
                new Table
            {
                Granularity    = Table.Types.TimestampGranularity.Millis,
                ColumnFamilies =
                {
                    { ColumnFamily1,     new ColumnFamily {
                          GcRule = new GcRule {
                              MaxNumVersions = 3
                          }
                      } },
                    { OtherColumnFamily, new ColumnFamily {
                          GcRule = new GcRule {
                              MaxNumVersions = 3
                          }
                      } }
                }
            });

            return(tableName);
        }
Beispiel #3
0
        public async Task <TableName> CreateTable()
        {
            var tableName = new TableName(ProjectName.ProjectId, InstanceName.InstanceId, Guid.NewGuid().ToString());

            CreatedTables.Add(tableName);
            await TableAdminClient.CreateTableAsync(
                new InstanceName(tableName.ProjectId, tableName.InstanceId),
                tableName.TableId,
                CreateDefaultTable());

            return(tableName);
        }
Beispiel #4
0
 public void EnsureTable <T>() where T : class
 {
     try
     {
         m_setupRepository.EnsureTableExists <T>();
         CreatedTables.Add(typeof(T).Name);
     }
     catch (Exception e)
     {
         Errors.Add(string.Format(
                        "{0}: {1}",
                        typeof(T).Name,
                        e.Message
                        ));
     }
 }
Beispiel #5
0
        private TableSource[] GetNormalizedDroppedTables()
        {
            // Create a normalized list of TableSource of all tables that
            // were dropped (and not created) in this transaction.  This list
            // represents tables that will be dropped if the transaction
            // successfully commits.

            var normalizedDroppedTables = new List <TableSource>(8);

            foreach (var tableId in DroppedTables)
            {
                // Was this dropped table also created?  If it was created in this
                // transaction then we don't care about it.
                if (!CreatedTables.Contains(tableId))
                {
                    TableSource masterTable = Composite.GetTableSource(tableId);
                    normalizedDroppedTables.Add(masterTable);
                }
            }

            return(normalizedDroppedTables.ToArray());
        }
Beispiel #6
0
        public void TestTableCalls()
        {
            var tables     = GetTableNames();
            int tableCount = tables.Count;

            // Create hash-key table
            var table1Name = TableNamePrefix + "Table1";

            Client.CreateTable(
                table1Name,
                new List <KeySchemaElement>
            {
                new KeySchemaElement {
                    KeyType = KeyType.HASH, AttributeName = "Id"
                }
            },
                new List <AttributeDefinition>
            {
                new AttributeDefinition {
                    AttributeName = "Id", AttributeType = ScalarAttributeType.N
                }
            },
                new ProvisionedThroughput {
                ReadCapacityUnits = DefaultReadCapacity, WriteCapacityUnits = DefaultWriteCapacity
            });
            CreatedTables.Add(table1Name);

            // Create hash-and-range-key table
            var table2Name = TableNamePrefix + "Table2";

            Client.CreateTable(
                table2Name,
                new List <KeySchemaElement>
            {
                new KeySchemaElement {
                    AttributeName = "Id", KeyType = KeyType.HASH
                },
                new KeySchemaElement {
                    AttributeName = "Name", KeyType = KeyType.RANGE
                }
            },
                new List <AttributeDefinition>
            {
                new AttributeDefinition {
                    AttributeName = "Id", AttributeType = ScalarAttributeType.N
                },
                new AttributeDefinition {
                    AttributeName = "Name", AttributeType = ScalarAttributeType.S
                }
            },
                new ProvisionedThroughput {
                ReadCapacityUnits = DefaultReadCapacity, WriteCapacityUnits = DefaultWriteCapacity
            });
            CreatedTables.Add(table2Name);

            // Create hash-key table with global index
            var table3Name = TableNamePrefix + "Table3";

            Client.CreateTable(new CreateTableRequest
            {
                TableName            = table3Name,
                AttributeDefinitions = new List <AttributeDefinition>
                {
                    new AttributeDefinition {
                        AttributeName = "Id", AttributeType = ScalarAttributeType.N
                    },
                    new AttributeDefinition {
                        AttributeName = "Company", AttributeType = ScalarAttributeType.S
                    },
                    new AttributeDefinition {
                        AttributeName = "Price", AttributeType = ScalarAttributeType.N
                    }
                },
                KeySchema = new List <KeySchemaElement>
                {
                    new KeySchemaElement {
                        KeyType = KeyType.HASH, AttributeName = "Id"
                    }
                },
                GlobalSecondaryIndexes = new List <GlobalSecondaryIndex>
                {
                    new GlobalSecondaryIndex
                    {
                        IndexName = "GlobalIndex",
                        KeySchema = new List <KeySchemaElement>
                        {
                            new KeySchemaElement {
                                AttributeName = "Company", KeyType = KeyType.HASH
                            },
                            new KeySchemaElement {
                                AttributeName = "Price", KeyType = KeyType.RANGE
                            }
                        },
                        ProvisionedThroughput = new ProvisionedThroughput {
                            ReadCapacityUnits = 1, WriteCapacityUnits = 1
                        },
                        Projection = new Projection {
                            ProjectionType = ProjectionType.ALL
                        }
                    }
                },
                ProvisionedThroughput = new ProvisionedThroughput {
                    ReadCapacityUnits = DefaultReadCapacity, WriteCapacityUnits = DefaultWriteCapacity
                },
            });
            CreatedTables.Add(table3Name);

            // Wait for tables to be ready before creating another table with an index
            WaitForTableStatus(CreatedTables, TableStatus.ACTIVE);

            // Create hash-and-range-key table with local and global indexes
            var table4Name = TableNamePrefix + "Table4";

            Client.CreateTable(new CreateTableRequest
            {
                TableName            = table4Name,
                AttributeDefinitions = new List <AttributeDefinition>
                {
                    new AttributeDefinition {
                        AttributeName = "Id", AttributeType = ScalarAttributeType.N
                    },
                    new AttributeDefinition {
                        AttributeName = "Name", AttributeType = ScalarAttributeType.S
                    },
                    new AttributeDefinition {
                        AttributeName = "Company", AttributeType = ScalarAttributeType.S
                    },
                    new AttributeDefinition {
                        AttributeName = "Price", AttributeType = ScalarAttributeType.N
                    },
                    new AttributeDefinition {
                        AttributeName = "Manager", AttributeType = ScalarAttributeType.S
                    }
                },
                KeySchema = new List <KeySchemaElement>
                {
                    new KeySchemaElement {
                        AttributeName = "Id", KeyType = KeyType.HASH
                    },
                    new KeySchemaElement {
                        AttributeName = "Name", KeyType = KeyType.RANGE
                    }
                },
                GlobalSecondaryIndexes = new List <GlobalSecondaryIndex>
                {
                    new GlobalSecondaryIndex
                    {
                        IndexName = "GlobalIndex",
                        KeySchema = new List <KeySchemaElement>
                        {
                            new KeySchemaElement {
                                AttributeName = "Company", KeyType = KeyType.HASH
                            },
                            new KeySchemaElement {
                                AttributeName = "Price", KeyType = KeyType.RANGE
                            }
                        },
                        ProvisionedThroughput = new ProvisionedThroughput {
                            ReadCapacityUnits = 1, WriteCapacityUnits = 1
                        },
                        Projection = new Projection {
                            ProjectionType = ProjectionType.ALL
                        }
                    }
                },
                LocalSecondaryIndexes = new List <LocalSecondaryIndex>
                {
                    new LocalSecondaryIndex
                    {
                        IndexName = "LocalIndex",
                        KeySchema = new List <KeySchemaElement>
                        {
                            new KeySchemaElement {
                                AttributeName = "Id", KeyType = KeyType.HASH
                            },
                            new KeySchemaElement {
                                AttributeName = "Manager", KeyType = KeyType.RANGE
                            }
                        },
                        Projection = new Projection
                        {
                            ProjectionType   = ProjectionType.INCLUDE,
                            NonKeyAttributes = new List <string> {
                                "Company", "Price"
                            }
                        }
                    }
                },
                ProvisionedThroughput = new ProvisionedThroughput {
                    ReadCapacityUnits = DefaultReadCapacity, WriteCapacityUnits = DefaultWriteCapacity
                },
            });
            CreatedTables.Add(table4Name);

            tables = GetTableNames();
            Assert.AreEqual(tableCount + 4, tables.Count);

            // Wait for tables to be ready
            WaitForTableStatus(CreatedTables, TableStatus.ACTIVE);

            // Update throughput for a table
            Client.UpdateTable(
                table2Name,
                new ProvisionedThroughput
            {
                ReadCapacityUnits  = DefaultReadCapacity * 2,
                WriteCapacityUnits = DefaultWriteCapacity * 2
            });

            // Wait for tables to be ready
            WaitForTableStatus(CreatedTables, TableStatus.ACTIVE);

            // Delete new tables
            Client.DeleteTable(table1Name);
            Client.DeleteTable(table2Name);
            Client.DeleteTable(table3Name);
            Client.DeleteTable(table4Name);

            // Wait for tables to be deleted
            WaitForTableStatus(new string[] { table1Name, table2Name, table3Name, table4Name }, null);

            // Count tables again
            tables = GetTableNames();
            Assert.AreEqual(tableCount, tables.Count);

            CreatedTables.Remove(table1Name);
            CreatedTables.Remove(table2Name);
            CreatedTables.Remove(table3Name);
            CreatedTables.Remove(table4Name);
        }
Beispiel #7
0
        internal IEnumerable <TableSource> Commit(IList <TransactionObjectState> nameSpaceJournals)
        {
            var changedTablesList = new List <TableSource>();

            // This is a transaction that will represent the view of the database
            // at the end of the commit
            ITransaction checkTransaction = null;

            bool entriesCommitted = false;

            try {
                // ---- Commit check stage ----
                CheckConflicts(nameSpaceJournals);

                // Tests passed so go on to commit,

                // ---- Commit stage ----

                var normalizedChangedTables = GetNormalizedChangedTables();
                var normalizedDroppedTables = GetNormalizedDroppedTables();

                // We now need to create a ITransaction object that we
                // use to send to the triggering mechanism.  This
                // object represents a very specific view of the
                // transaction.  This view contains the latest version of changed
                // tables in this transaction.  It also contains any tables that have
                // been created by this transaction and does not contain any tables
                // that have been dropped.  Any tables that have not been touched by
                // this transaction are shown in their current committed state.
                // To summarize - this view is the current view of the database plus
                // any modifications made by the transaction that is being committed.

                // How this works - All changed tables are merged with the current
                // committed table.  All created tables are added into check_transaction
                // and all dropped tables are removed from check_transaction.  If
                // there were no other changes to a table between the time the
                // transaction was created and now, the view of the table in the
                // transaction is used, otherwise the latest changes are merged.

                // Note that this view will be the view that the database will
                // ultimately become if this transaction successfully commits.  Also,
                // you should appreciate that this view is NOT exactly the same as
                // the current trasaction view because any changes that have been
                // committed by concurrent transactions will be reflected in this view.

                // Create a new transaction of the database which will represent the
                // committed view if this commit is successful.
                checkTransaction = Composite.CreateTransaction(IsolationLevel.Serializable);

                // Overwrite this view with tables from this transaction that have
                // changed or have been added or dropped.

                // (Note that order here is important).  First drop any tables from
                // this view.
                foreach (TableSource masterTable in normalizedDroppedTables)
                {
                    // Drop this table in the current view
                    checkTransaction.RemoveVisibleTable(masterTable);
                }

                // Now add any changed tables to the view.

                // Represents view of the changed tables
                var changedTableSource = FindChangedTables(checkTransaction, normalizedChangedTables);

                // The 'checkTransaction' now represents the view the database will be
                // if the commit succeeds.  We Lock 'checkTransaction' so it is
                // Read-only (the view is immutable).
                checkTransaction.ReadOnly(true);

                CheckConstraintViolations(checkTransaction, normalizedChangedTables, changedTableSource);

                // Deferred trigger events.
                FireChangeEvents(normalizedChangedTables);

                // NOTE: This isn't as fail safe as it could be.  We really need to
                //  do the commit in two phases.  The first writes updated indices to
                //  the index files.  The second updates the header pointer for the
                //  respective table.  Perhaps we can make the header update
                //  procedure just one file Write.

                // Finally, at this point all constraint checks have passed and the
                // changes are ready to finally be committed as permanent changes
                // to the Composite.  All that needs to be done is to commit our
                // IIndexSet indices for each changed table as final.
                // ISSUE: Should we separate the 'committing of indexes' changes and
                //   'committing of delete/add flags' to make the FS more robust?
                //   It would be more robust if all indexes are committed in one go,
                //   then all table flag data.

                // Set flag to indicate we have committed entries.
                entriesCommitted = true;

                // For each change to each table,
                foreach (CommitTableInfo tableInfo in normalizedChangedTables)
                {
                    // Get the journal that details the change to the table.
                    TableEventRegistry changeJournal = tableInfo.Journal;
                    if (changeJournal != null)
                    {
                        // Get the master table with this table id.
                        TableSource master = tableInfo.Master;
                        // Commit the changes to the table.
                        // We use 'this.commit_id' which is the current commit level we are
                        // at.
                        master.CommitTransactionChange(Composite.CurrentCommitId, changeJournal, tableInfo.IndexSet);
                        // Add to 'changed_tables_list'
                        changedTablesList.Add(master);
                    }
                }

                // Only do this if we've created or dropped tables.
                if (CreatedTables.Any() || DroppedTables.Any())
                {
                    // Update the committed tables in the Composite state.
                    // This will update and synchronize the headers in this Composite.
                    Composite.CommitToTables(CreatedTables, DroppedTables);
                }

                // Update the namespace clash list
                if (ObjectsCreated.Any() || ObjectsDropped.Any())
                {
                    nameSpaceJournals.Add(new TransactionObjectState(CommitId, ObjectsCreated, ObjectsDropped));
                }
            } finally {
                try {
                    // If entries_committed == false it means we didn't get to a point
                    // where any changed tables were committed.  Attempt to rollback the
                    // changes in this transaction if they haven't been committed yet.
                    if (entriesCommitted == false)
                    {
                        // For each change to each table,
                        foreach (TableEventRegistry changeJournal in ChangedTables)
                        {
                            // The table the changes were made to.
                            int tableId = changeJournal.TableId;
                            // Get the master table with this table id.
                            TableSource master = Composite.GetTableSource(tableId);
                            // Commit the rollback on the table.
                            master.RollbackTransactionChange(changeJournal);
                        }

                        // TODO: Notify the system we're rolling back
                    }
                } finally {
                    try {
                        // Dispose the 'checkTransaction'
                        if (checkTransaction != null)
                        {
                            checkTransaction.Dispose();
                            Composite.CloseTransaction(checkTransaction);
                        }
                        // Always ensure a transaction close, even if we have an exception.
                        // Notify the Composite that this transaction has closed.
                        Composite.CloseTransaction(Transaction);
                    } catch (Exception) {
                        // TODO: notify the error
                    } finally {
                        Done = true;
                    }
                }
            }

            return(changedTablesList.ToArray());
        }
Beispiel #8
0
        private void CheckConflicts(IEnumerable <TransactionObjectState> namespaceJournals)
        {
            AssertNoDirtySelect();

            // Check there isn't a namespace clash with database objects.
            // We need to create a list of all create and drop activity in the
            // Composite from when the transaction started.
            var allDroppedObs = new List <ObjectName>();
            var allCreatedObs = new List <ObjectName>();

            foreach (var nsJournal in namespaceJournals)
            {
                if (nsJournal.CommitId >= CommitId)
                {
                    allDroppedObs.AddRange(nsJournal.DroppedObjects);
                    allCreatedObs.AddRange(nsJournal.CreatedObjects);
                }
            }

            // The list of all dropped objects since this transaction
            // began.
            bool       conflict5    = false;
            ObjectName conflictName = null;
            string     conflictDesc = "";

            foreach (ObjectName droppedOb in allDroppedObs)
            {
                if (ObjectsDropped.Contains(droppedOb))
                {
                    conflict5    = true;
                    conflictName = droppedOb;
                    conflictDesc = "dropped";
                }
            }
            // The list of all created objects since this transaction
            // began.
            foreach (ObjectName createdOb in allCreatedObs)
            {
                if (ObjectsCreated.Contains(createdOb))
                {
                    conflict5    = true;
                    conflictName = createdOb;
                    conflictDesc = "created";
                }
            }
            if (conflict5)
            {
                // Namespace conflict...
                throw new ObjectDuplicatedConflictException(conflictName, conflictDesc);
            }

            // For each journal,
            foreach (TableEventRegistry changeJournal in ChangedTables)
            {
                // The table the change was made to.
                int tableId = changeJournal.TableId;
                // Get the master table with this table id.
                TableSource master = Composite.GetTableSource(tableId);

                // True if the state contains a committed resource with the given name
                bool committedResource = Composite.ContainsVisibleResource(tableId);

                // Check this table is still in the committed tables list.
                if (!CreatedTables.Contains(tableId) && !committedResource)
                {
                    // This table is no longer a committed table, so rollback
                    throw new NonCommittedConflictException(master.TableName);
                }

                // Since this journal was created, check to see if any changes to the
                // tables have been committed since.
                // This will return all journals on the table with the same commit_id
                // or greater.
                var journalsSince = master.FindChangesSinceCmmit(CommitId);

                // For each journal, determine if there's any clashes.
                foreach (TableEventRegistry tableJournal in journalsSince)
                {
                    // This will thrown an exception if a commit classes.
                    changeJournal.TestCommitClash(master.TableInfo, tableJournal);
                }
            }

            // Look at the transaction journal, if a table is dropped that has
            // journal entries since the last commit then we have an exception
            // case.
            foreach (int tableId in DroppedTables)
            {
                // Get the master table with this table id.
                TableSource master = Composite.GetTableSource(tableId);
                // Any journal entries made to this dropped table?
                if (master.FindChangesSinceCmmit(CommitId).Any())
                {
                    // Oops, yes, rollback!
                    throw new DroppedModifiedObjectConflictException(master.TableName);
                }
            }
        }
Beispiel #9
0
        public void TestTableCalls()
        {
            // Only run these tests if we are not reusing tables
            if (ReuseTables)
            {
                return;
            }

            var tables     = GetTableNames();
            int tableCount = tables.Count;

            // Create hash-key table
            var table1Name = TableNamePrefix + "Table1";

            Client.CreateTable(
                new CreateTableRequest
            {
                TableName = table1Name,
                KeySchema = new List <KeySchemaElement>
                {
                    new KeySchemaElement {
                        KeyType = KeyType.HASH, AttributeName = "Id"
                    }
                },
                AttributeDefinitions = new List <AttributeDefinition>
                {
                    new AttributeDefinition {
                        AttributeName = "Id", AttributeType = ScalarAttributeType.N
                    }
                },
                BillingMode = BillingMode.PAY_PER_REQUEST
            });
            CreatedTables.Add(table1Name);

            // Create hash-and-range-key table
            var table2Name = TableNamePrefix + "Table2";

            Client.CreateTable(new CreateTableRequest
            {
                TableName = table2Name,
                KeySchema = new List <KeySchemaElement>
                {
                    new KeySchemaElement {
                        AttributeName = "Id", KeyType = KeyType.HASH
                    },
                    new KeySchemaElement {
                        AttributeName = "Name", KeyType = KeyType.RANGE
                    }
                },
                AttributeDefinitions = new List <AttributeDefinition>
                {
                    new AttributeDefinition {
                        AttributeName = "Id", AttributeType = ScalarAttributeType.N
                    },
                    new AttributeDefinition {
                        AttributeName = "Name", AttributeType = ScalarAttributeType.S
                    }
                },
                BillingMode = BillingMode.PAY_PER_REQUEST
            });
            CreatedTables.Add(table2Name);

            // Create hash-key table with global index
            var table3Name = TableNamePrefix + "Table3";

            Client.CreateTable(new CreateTableRequest
            {
                TableName            = table3Name,
                AttributeDefinitions = new List <AttributeDefinition>
                {
                    new AttributeDefinition {
                        AttributeName = "Id", AttributeType = ScalarAttributeType.N
                    },
                    new AttributeDefinition {
                        AttributeName = "Company", AttributeType = ScalarAttributeType.S
                    },
                    new AttributeDefinition {
                        AttributeName = "Price", AttributeType = ScalarAttributeType.N
                    }
                },
                KeySchema = new List <KeySchemaElement>
                {
                    new KeySchemaElement {
                        KeyType = KeyType.HASH, AttributeName = "Id"
                    }
                },
                GlobalSecondaryIndexes = new List <GlobalSecondaryIndex>
                {
                    new GlobalSecondaryIndex
                    {
                        IndexName = "GlobalIndex",
                        KeySchema = new List <KeySchemaElement>
                        {
                            new KeySchemaElement {
                                AttributeName = "Company", KeyType = KeyType.HASH
                            },
                            new KeySchemaElement {
                                AttributeName = "Price", KeyType = KeyType.RANGE
                            }
                        },
                        Projection = new Projection {
                            ProjectionType = ProjectionType.ALL
                        }
                    }
                },
                BillingMode = BillingMode.PAY_PER_REQUEST
            });
            CreatedTables.Add(table3Name);

            // Wait for tables to be ready before creating another table with an index
            WaitForTableStatus(CreatedTables, TableStatus.ACTIVE);

            // Create hash-and-range-key table with local and global indexes
            var table4Name = TableNamePrefix + "Table4";

            Client.CreateTable(new CreateTableRequest
            {
                TableName            = table4Name,
                AttributeDefinitions = new List <AttributeDefinition>
                {
                    new AttributeDefinition {
                        AttributeName = "Id", AttributeType = ScalarAttributeType.N
                    },
                    new AttributeDefinition {
                        AttributeName = "Name", AttributeType = ScalarAttributeType.S
                    },
                    new AttributeDefinition {
                        AttributeName = "Company", AttributeType = ScalarAttributeType.S
                    },
                    new AttributeDefinition {
                        AttributeName = "Price", AttributeType = ScalarAttributeType.N
                    },
                    new AttributeDefinition {
                        AttributeName = "Manager", AttributeType = ScalarAttributeType.S
                    }
                },
                KeySchema = new List <KeySchemaElement>
                {
                    new KeySchemaElement {
                        AttributeName = "Id", KeyType = KeyType.HASH
                    },
                    new KeySchemaElement {
                        AttributeName = "Name", KeyType = KeyType.RANGE
                    }
                },
                GlobalSecondaryIndexes = new List <GlobalSecondaryIndex>
                {
                    new GlobalSecondaryIndex
                    {
                        IndexName = "GlobalIndex",
                        KeySchema = new List <KeySchemaElement>
                        {
                            new KeySchemaElement {
                                AttributeName = "Company", KeyType = KeyType.HASH
                            },
                            new KeySchemaElement {
                                AttributeName = "Price", KeyType = KeyType.RANGE
                            }
                        },
                        Projection = new Projection {
                            ProjectionType = ProjectionType.ALL
                        }
                    }
                },
                LocalSecondaryIndexes = new List <LocalSecondaryIndex>
                {
                    new LocalSecondaryIndex
                    {
                        IndexName = "LocalIndex",
                        KeySchema = new List <KeySchemaElement>
                        {
                            new KeySchemaElement {
                                AttributeName = "Id", KeyType = KeyType.HASH
                            },
                            new KeySchemaElement {
                                AttributeName = "Manager", KeyType = KeyType.RANGE
                            }
                        },
                        Projection = new Projection
                        {
                            ProjectionType   = ProjectionType.INCLUDE,
                            NonKeyAttributes = new List <string> {
                                "Company", "Price"
                            }
                        }
                    }
                },
                BillingMode = BillingMode.PAY_PER_REQUEST
            });
            CreatedTables.Add(table4Name);

            tables = GetTableNames();
            Assert.AreEqual(tableCount + 4, tables.Count);

            // Wait for tables to be ready
            WaitForTableStatus(CreatedTables, TableStatus.ACTIVE);

            // Delete new tables
            Client.DeleteTable(table1Name);
            Client.DeleteTable(table2Name);
            Client.DeleteTable(table3Name);
            Client.DeleteTable(table4Name);

            // Wait for tables to be deleted
            WaitForTableStatus(new string[] { table1Name, table2Name, table3Name, table4Name }, null);

            // Count tables again
            tables = GetTableNames();
            Assert.AreEqual(tableCount, tables.Count);

            CreatedTables.Remove(table1Name);
            CreatedTables.Remove(table2Name);
            CreatedTables.Remove(table3Name);
            CreatedTables.Remove(table4Name);
        }