18 using System.Collections.Generic;
26 namespace Deveel.Data.Sql.Sequences {
47 sequenceKeyMap =
new Dictionary<ObjectName, Sequence>();
60 if (sequenceKeyMap !=null)
61 sequenceKeyMap.Clear();
63 sequenceKeyMap = null;
69 GC.SuppressFinalize(
this);
81 #region SequenceTableContainer
89 this.manager = manager;
92 public int TableCount {
95 return table != null ? table.RowCount : 0;
110 info = info.AsReadOnly();
115 if (tableName == null)
116 throw new ArgumentNullException(
"tableName");
118 if (tableName.
Parent == null)
122 if (transaction.RealTableExists(seqInfo)) {
124 var table = transaction.GetTable(seqInfo);
129 foreach (var row
in table) {
130 var seqType = row.GetValue(3);
131 if (!seqType.IsEqualTo(OneValue)) {
132 var obName = row.GetValue(2);
133 if (obName.IsEqualTo(name)) {
134 var obSchema = row.GetValue(1);
135 if (obSchema.IsEqualTo(schema)) {
150 if (transaction.RealTableExists(seqInfo)) {
151 var table = transaction.GetTable(seqInfo);
153 foreach (var row
in table) {
154 var seqType = row.GetValue(3);
155 if (!seqType.IsEqualTo(OneValue)) {
157 var obSchema = row.GetValue(1);
158 var obName = row.GetValue(2);
166 throw new ArgumentOutOfRangeException(
"offset");
170 var tableName = GetTableName(offset);
171 return CreateTableInfo(tableName.Parent, tableName.Name);
187 return FindByName(name) != -1;
195 foreach (var row
in table) {
197 if (seqType.IsEqualTo(OneValue)) {
199 rowIndex = row.RowId.RowNumber;
208 throw new ArgumentOutOfRangeException(
"offset");
210 var seqId = table.GetValue(rowIndex, 0);
211 var schema =
ObjectName.
Parse(table.GetValue(rowIndex, 1).Value.ToString());
212 var name = table.GetValue(rowIndex, 2).Value.
ToString();
219 var index = seqTable.GetIndex(0);
220 var list = index.SelectEqual(seqId);
223 throw new Exception(
"No SEQUENCE table entry for sequence.");
225 int seqRowI = list.First();
228 var tableInfo = CreateTableInfo(schema, name);
233 var sequence = manager.GetSequence(tableName);
234 if (sequence == null)
238 }
catch (Exception) {
246 var topValue = seqTable.GetValue(seqRowI, 1);
247 var incrementBy = seqTable.GetValue(seqRowI, 2);
248 var minValue = seqTable.GetValue(seqRowI, 3);
249 var maxValue = seqTable.GetValue(seqRowI, 4);
250 var start = seqTable.GetValue(seqRowI, 5);
251 var cache = seqTable.GetValue(seqRowI, 6);
252 var cycle = seqTable.GetValue(seqRowI, 7);
255 return new SequenceTable(transaction.Database.Context, tableInfo) {
257 LastValue = lastValue,
258 CurrentValue = currentValue,
259 Increment = incrementBy,
271 #region SequenceTable
278 this.tableInfo = tableInfo;
282 get {
return tableInfo; }
285 public override int RowCount {
309 throw new ArgumentOutOfRangeException(
"rowNumber");
311 switch (columnOffset) {
331 throw new ArgumentOutOfRangeException(
"columnOffset");
356 var count = list.Count();
361 throw new Exception(
"Assert failed: multiple id for sequence.");
364 var dataRow = seq.GetRow(list.First());
377 seq.UpdateRow(dataRow);
387 tableInfo = tableInfo.AsReadOnly();
400 tableInfo = tableInfo.AsReadOnly();
407 throw new ArgumentException();
409 CreateSequence(seqInfo);
413 if (sequenceInfo == null)
414 throw new ArgumentNullException(
"sequenceInfo");
428 return CreateNativeTableSequence(sequenceName);
430 return CreateCustomSequence(sequenceName, sequenceInfo);
440 throw new Exception(
String.Format(
"Sequence generator with name '{0}' already exists.", sequenceName));
446 var dataRow = seqi.NewRow();
451 seqi.AddRow(dataRow);
454 dataRow = seq.NewRow();
465 return new Sequence(
this, uniqueId, sequenceInfo);
472 var dataRow = table.NewRow();
477 table.AddRow(dataRow);
483 throw new NotImplementedException();
487 return DropSequence(objName);
491 throw new NotImplementedException();
499 throw new Exception(
"System sequence tables do not exist.");
503 return RemoveNativeTableSequence(sequenceName);
523 foreach (var rowIndex
in list) {
524 var sid = seqi.GetValue(rowIndex, 0);
525 var list2 = seq.SelectRowsEqual(0, sid);
526 foreach (
int rowIndex2
in list2) {
528 seq.RemoveRow(rowIndex2);
532 seqi.RemoveRow(rowIndex);
539 return SequenceExists(objName);
543 return SequenceExists(objName);
551 throw new Exception(
"System sequence tables do not exist.");
564 var sequence = (
Sequence)GetSequence(name);
571 var currentVal = sequence.CurrentValue;
574 sequence.IncrementCurrentValue();
577 if (currentVal == sequence.LastValue) {
579 for (
int i = 0; i < sequence.SequenceInfo.Cache; ++i) {
580 sequence.IncrementLastValue();
584 UpdateSequenceState(sequence);
588 return sequence.CurrentValue;
594 var sequence = (
Sequence) GetSequence(name);
600 sequence.CurrentValue = value;
601 sequence.LastValue = value;
604 UpdateSequenceState(sequence);
612 var sequence = (
Sequence) GetSequence(name);
618 return sequence.CurrentValue;
623 return GetSequence(objName);
630 if (!sequenceKeyMap.TryGetValue(sequenceName, out sequence)) {
637 var list = seqi.SelectRowsEqual(2, nameVal, 1, schemaVal).ToList();
639 if (list.Count == 0) {
640 throw new ArgumentException(
String.Format(
"Sequence '{0}' not found.", sequenceName));
641 }
else if (list.Count() > 1) {
642 throw new Exception(
"Assert failed: multiple sequence keys with same name.");
645 int rowIndex = list.First();
646 var sid = seqi.GetValue(rowIndex, 0);
647 var sschema = seqi.GetValue(rowIndex, 1);
648 var sname = seqi.GetValue(rowIndex, 2);
649 var stype = seqi.GetValue(rowIndex, 3);
653 if (stype.IsEqualTo(OneValue)) {
660 list = seq.SelectRowsEqual(0, sid).ToList();
663 throw new Exception(
"Sequence table does not contain sequence information.");
664 if (list.Count() > 1)
665 throw new Exception(
"Sequence table contains multiple generators for id.");
667 rowIndex = list.First();
668 var lastValue = (
SqlNumber) seq.GetValue(rowIndex, 1).Value;
669 var increment = (
SqlNumber) seq.GetValue(rowIndex, 2).Value;
670 var minvalue = (
SqlNumber) seq.GetValue(rowIndex, 3).Value;
671 var maxvalue = (
SqlNumber) seq.GetValue(rowIndex, 4).Value;
672 var start = (
SqlNumber) seq.GetValue(rowIndex, 5).Value;
673 var cache = (long) seq.GetValue(rowIndex, 6).AsBigInt();
674 bool cycle = seq.GetValue(rowIndex, 7).AsBoolean();
676 var info =
new SequenceInfo(sequenceName, start, increment, minvalue, maxvalue, cache, cycle);
680 sequenceKeyMap[sequenceName] = sequence;
700 this.manager = manager;
704 LastValue = lastValue;
705 CurrentValue = lastValue;
723 return manager.GetCurrentValue(FullName);
727 return manager.NextValue(FullName);
731 return manager.SetValue(FullName, value);
740 throw new InvalidOperationException(
"Sequence out of bounds.");
747 throw new InvalidOperationException(
"Sequence out of bounds.");
754 CurrentValue = IncrementValue(CurrentValue);
758 LastValue = IncrementValue(LastValue);
Provides some helper functions for resolving and creating SqlType instances that are primitive to the...
bool RemoveNativeTableSequence(ObjectName tableName)
SqlNumber GetCurrentValue(ObjectName name)
static TableInfo CreateTableInfo(ObjectName schema, string name)
bool AlterObject(IObjectInfo objInfo)
Modifies an existing object managed, identified by IObjectInfo.FullName component of the given specif...
static DataObject Integer(int value)
bool DropObject(ObjectName objName)
Deletes a database object handled by this manager from the system.
Defines the contract to access the data contained into a table of a database.
static ObjectName Parse(string s)
Parses the given string into a ObjectName object.
bool ContainsTable(ObjectName name)
Checks if a table with the given name is contained in the current context.
override string ToString()
SqlNumber Increment
Gets the configured incremental value, that is the value added to the current value of a sequence eac...
Sequence(SequenceManager manager, SqlNumber id, SqlNumber lastValue, SequenceInfo sequenceInfo)
A long string in the system.
The context of a single database within a system.
The system implementation of a transaction model that handles isolated operations within a database c...
static readonly ObjectName SequenceTableName
long Cache
Gets the number of items of the sequence to cache.
bool RealObjectExists(ObjectName objName)
Checks if an object really exists in the system.
static BooleanType Boolean()
void IncrementLastValue()
Sequence(SequenceManager manager, SqlNumber id, SequenceInfo sequenceInfo)
SequenceTable(IDatabaseContext dbContext, TableInfo tableInfo)
SqlNumber MaxValue
Gets the configured maximum value of the sequence.
static DataObject Number(SqlNumber value)
Represents a database object, such as a table, a trigger, a type or a column.
ISequence CreateSequence(SequenceInfo sequenceInfo)
SqlNumber StartValue
Gets the configured starting numeric value of a sequence.
Sequence CreateCustomSequence(ObjectName sequenceName, SequenceInfo sequenceInfo)
SqlNumber SetValue(ObjectName name, SqlNumber value)
Describes the name of an object within a database.
SqlNumber GetCurrentValue()
static DataObject Boolean(SqlBoolean value)
override bool Equals(object obj)
ISequence GetSequence(ObjectName sequenceName)
SequenceTableContainer(SequenceManager manager)
DataObject GetValue(long rowNumber, int columnOffset)
Gets a single cell within the table that is located at the given column offset and row...
readonly TableInfo tableInfo
ObjectName ResolveName(ObjectName objName, bool ignoreCase)
Normalizes the input object name using the case sensitivity specified.
readonly SequenceManager manager
A default implementation of a sequence manager that is backed by a given transaction.
override DataObject GetValue(long rowNumber, int columnOffset)
Gets a single cell within the table that is located at the given column offset and row...
SqlNumber IncrementValue(SqlNumber val)
static NumericType Numeric()
void CreateObject(IObjectInfo objInfo)
Create a new object of the ObjectType given the specifications given.
Provides the meta information about a ISequence configuring its operative behavior.
Provides the constant names of the types of tables in a database system.
void IncrementCurrentValue()
bool DropSequence(ObjectName sequenceName)
bool SequenceExists(ObjectName sequenceName)
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
static SequenceInfo Native(ObjectName tableName)
Creates an object that describes a native sequence for the table having the specified name...
ITransaction Transaction
Gets the transaction where the manager is operating.
A container for any system tables that are generated from information inside the database engine...
DbObjectType ObjectType
Gets the type of database object that the implementation is for
Provides utilities and properties for handling the SYSTEN schema of a database.
string FullName
Gets the full reference name formatted.
DbObjectType ObjectType
Gets the type of objects managed by this instance.
SqlNumber SetValue(SqlNumber value)
static readonly ObjectName SequenceInfoTableName
readonly ITransaction transaction
void UpdateSequenceState(Sequence sequence)
Updates the state of the sequence key in the sequence tables in the database.
SequenceInfo SequenceInfo
ObjectName Parent
Gets the parent reference of the current one, if any or null if none.
SqlNumber MinValue
Gets the configured minimum value of the sequence.
static DataObject VarChar(string s)
Dictionary< ObjectName, Sequence > sequenceKeyMap
static DataObject BigInt(long value)
string Name
Gets the name of the object being referenced.
readonly SequenceManager manager
ObjectName GetTableName(int offset)
Gets the name of the table at the given index in this container.
SequenceManager(ITransaction transaction)
Construct a new instance of SequenceManager that is backed by the given transaction factory...
static StringType String()
TableInfo GetTableInfo(int offset)
Gets the information of the table at the given offset in this container.
void Create()
Initializes the manager into the underlying system.
string GetTableType(int offset)
Gets the type of the table at the given offset.
IDbObject GetObject(ObjectName objName)
Gets a database object managed by this manager.
bool ObjectExists(ObjectName objName)
Checks if an object identified by the given name is managed by this instance.
bool Cycle
Gets true if the sequence will cycle when it reaches either MinValue or MaxValue. ...
Defines the contract for the business managers of database objects of a given type.
The simplest implementation of a transaction.
ISequence CreateNativeTableSequence(ObjectName tableName)
DbObjectType
The kind of objects that can be handled by a database system and its managers
Defines the metadata properties of a table existing within a database.
int FindByName(ObjectName tableName)
Finds the index in this container of the given table by its name.
SqlNumber NextValue(ObjectName name)
SequenceType
The form of a ISequence object in a transaction.
void Dispose(bool disposing)
Manages the sequences within an isolated context.
ITable GetTable(int offset)
Gets the table contained at the given offset within the context.
Represents a numberic sequence in a transaction.