DeveelDB  20151217
complete SQL database system, primarly developed for .NET/Mono frameworks
SequenceManager.cs
Go to the documentation of this file.
1 //
2 // Copyright 2010-2015 Deveel
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 using System;
18 using System.Collections.Generic;
19 using System.Linq;
20 
21 using Deveel.Data.Sql.Objects;
22 using Deveel.Data.Sql.Tables;
24 using Deveel.Data.Types;
25 
26 namespace Deveel.Data.Sql.Sequences {
36  private static readonly DataObject OneValue = DataObject.Integer(1);
37 
38  private Dictionary<ObjectName, Sequence> sequenceKeyMap;
39 
45  public SequenceManager(ITransaction transaction) {
46  Transaction = transaction;
47  sequenceKeyMap = new Dictionary<ObjectName, Sequence>();
48  }
49 
51  Dispose(false);
52  }
53 
55  get { return DbObjectType.Sequence; }
56  }
57 
58  private void Dispose(bool disposing) {
59  if (disposing) {
60  if (sequenceKeyMap !=null)
61  sequenceKeyMap.Clear();
62 
63  sequenceKeyMap = null;
64  }
65  }
66 
67  public void Dispose() {
68  Dispose(true);
69  GC.SuppressFinalize(this);
70  }
71 
75  private ITransaction Transaction { get; set; }
76 
77  public ITableContainer TableContainer {
78  get { return new SequenceTableContainer(this); }
79  }
80 
81  #region SequenceTableContainer
82 
84  private readonly ITransaction transaction;
85  private readonly SequenceManager manager;
86 
88  transaction = manager.Transaction;
89  this.manager = manager;
90  }
91 
92  public int TableCount {
93  get {
94  var table = transaction.GetTable(SystemSchema.SequenceTableName);
95  return table != null ? table.RowCount : 0;
96  }
97  }
98 
99  private static TableInfo CreateTableInfo(ObjectName schema, string name) {
100  var info = new TableInfo(new ObjectName(schema, name));
101  info.AddColumn("last_value", PrimitiveTypes.Numeric());
102  info.AddColumn("current_value", PrimitiveTypes.Numeric());
103  info.AddColumn("top_value", PrimitiveTypes.Numeric());
104  info.AddColumn("increment_by", PrimitiveTypes.Numeric());
105  info.AddColumn("min_value", PrimitiveTypes.Numeric());
106  info.AddColumn("max_value", PrimitiveTypes.Numeric());
107  info.AddColumn("start", PrimitiveTypes.Numeric());
108  info.AddColumn("cache", PrimitiveTypes.Numeric());
109  info.AddColumn("cycle", PrimitiveTypes.Boolean());
110  info = info.AsReadOnly();
111  return info;
112  }
113 
114  public int FindByName(ObjectName tableName) {
115  if (tableName == null)
116  throw new ArgumentNullException("tableName");
117 
118  if (tableName.Parent == null)
119  return -1;
120 
121  var seqInfo = SystemSchema.SequenceInfoTableName;
122  if (transaction.RealTableExists(seqInfo)) {
123  // Search the table.
124  var table = transaction.GetTable(seqInfo);
125  var name = DataObject.VarChar(tableName.Name);
126  var schema = DataObject.VarChar(tableName.Parent.FullName);
127 
128  int p = 0;
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)) {
136  // Match so return this
137  return p;
138  }
139  }
140  ++p;
141  }
142  }
143  }
144 
145  return -1;
146  }
147 
148  public ObjectName GetTableName(int offset) {
149  var seqInfo = SystemSchema.SequenceInfoTableName;
150  if (transaction.RealTableExists(seqInfo)) {
151  var table = transaction.GetTable(seqInfo);
152  int p = 0;
153  foreach (var row in table) {
154  var seqType = row.GetValue(3);
155  if (!seqType.IsEqualTo(OneValue)) {
156  if (offset == p) {
157  var obSchema = row.GetValue(1);
158  var obName = row.GetValue(2);
159  return new ObjectName(ObjectName.Parse(obSchema.Value.ToString()), obName.Value.ToString());
160  }
161  ++p;
162  }
163  }
164  }
165 
166  throw new ArgumentOutOfRangeException("offset");
167  }
168 
169  public TableInfo GetTableInfo(int offset) {
170  var tableName = GetTableName(offset);
171  return CreateTableInfo(tableName.Parent, tableName.Name);
172  }
173 
174  public string GetTableType(int offset) {
175  return TableTypes.Sequence;
176  }
177 
178  public bool ContainsTable(ObjectName name) {
179  var seqInfo = SystemSchema.SequenceInfoTableName;
180 
181  // This set can not contain the table that is backing it, so we always
182  // return false for that. This check stops an annoying recursive
183  // situation for table name resolution.
184  if (name.Equals(seqInfo))
185  return false;
186 
187  return FindByName(name) != -1;
188  }
189 
190  public ITable GetTable(int offset) {
191  var table = transaction.GetTable(SystemSchema.SequenceInfoTableName);
192  int p = 0;
193  int rowIndex = -1;
194 
195  foreach (var row in table) {
196  var seqType = row.GetValue(3);
197  if (seqType.IsEqualTo(OneValue)) {
198  if (p == offset) {
199  rowIndex = row.RowId.RowNumber;
200  break;
201  }
202 
203  p++;
204  }
205  }
206 
207  if (rowIndex == -1)
208  throw new ArgumentOutOfRangeException("offset");
209 
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();
213 
214  var tableName = new ObjectName(schema, name);
215 
216  // Find this id in the 'sequence' table
217  var seqTable = transaction.GetTable(SystemSchema.SequenceTableName);
218 
219  var index = seqTable.GetIndex(0);
220  var list = index.SelectEqual(seqId);
221 
222  if (!list.Any())
223  throw new Exception("No SEQUENCE table entry for sequence.");
224 
225  int seqRowI = list.First();
226 
227  // Generate the DataTableInfo
228  var tableInfo = CreateTableInfo(schema, name);
229 
230  // Last value for this sequence generated by the transaction
231  DataObject lastValue;
232  try {
233  var sequence = manager.GetSequence(tableName);
234  if (sequence == null)
235  throw new ObjectNotFoundException(tableName);
236 
237  lastValue = DataObject.Number(sequence.GetCurrentValue());
238  } catch (Exception) {
239  lastValue = DataObject.BigInt(-1);
240  }
241 
242  // The current value of the sequence generator
243  var currentValue = DataObject.Number(manager.GetCurrentValue(tableName));
244 
245  // Read the rest of the values from the SEQUENCE table.
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);
253 
254 
255  return new SequenceTable(transaction.Database.Context, tableInfo) {
256  TopValue = topValue,
257  LastValue = lastValue,
258  CurrentValue = currentValue,
259  Increment = incrementBy,
260  MinValue = minValue,
261  MaxValue = maxValue,
262  Start = start,
263  Cache = cache,
264  Cycle = cycle
265  };
266  }
267  }
268 
269  #endregion
270 
271  #region SequenceTable
272 
274  private readonly TableInfo tableInfo;
275 
276  public SequenceTable(IDatabaseContext dbContext, TableInfo tableInfo)
277  : base(dbContext) {
278  this.tableInfo = tableInfo;
279  }
280 
281  public override TableInfo TableInfo {
282  get { return tableInfo; }
283  }
284 
285  public override int RowCount {
286  get { return 1; }
287  }
288 
289  public DataObject TopValue { get; set; }
290 
291  public DataObject LastValue { get; set; }
292 
293  public DataObject CurrentValue { get; set; }
294 
295  public DataObject Increment { get; set; }
296 
297  public DataObject MinValue { get; set; }
298 
299  public DataObject MaxValue { get; set; }
300 
301  public DataObject Start { get; set; }
302 
303  public DataObject Cache { get; set; }
304 
305  public DataObject Cycle { get; set; }
306 
307  public override DataObject GetValue(long rowNumber, int columnOffset) {
308  if (rowNumber != 0)
309  throw new ArgumentOutOfRangeException("rowNumber");
310 
311  switch (columnOffset) {
312  case 0:
313  return LastValue;
314  case 1:
315  return CurrentValue;
316  case 2:
317  return TopValue;
318  case 3:
319  return Increment;
320  case 4:
321  return MinValue;
322  case 5:
323  return MaxValue;
324  case 6:
325  return Start;
326  case 7:
327  return Cache;
328  case 8:
329  return Cycle;
330  default:
331  throw new ArgumentOutOfRangeException("columnOffset");
332  }
333  }
334  }
335 
336  #endregion
337 
346  private void UpdateSequenceState(Sequence sequence) {
347  // We need to update the sequence key state.
348 
349  // The sequence table
350  var seq = Transaction.GetMutableTable(SystemSchema.SequenceTableName);
351 
352  // Find the row with the id for this sequence.
353  var list = seq.SelectRowsEqual(0, DataObject.Number(sequence.Id)).ToList();
354 
355  // Checks
356  var count = list.Count();
357  if (count == 0)
358  throw new ObjectNotFoundException(sequence.FullName);
359 
360  if (count > 1)
361  throw new Exception("Assert failed: multiple id for sequence.");
362 
363  // Create the DataRow
364  var dataRow = seq.GetRow(list.First());
365 
366  // Set the content of the row data
367  dataRow.SetValue(0, DataObject.Number(sequence.Id));
368  dataRow.SetValue(1, DataObject.Number(sequence.LastValue));
369  dataRow.SetValue(2, DataObject.Number(sequence.SequenceInfo.Increment));
370  dataRow.SetValue(3, DataObject.Number(sequence.SequenceInfo.MinValue));
371  dataRow.SetValue(4, DataObject.Number(sequence.SequenceInfo.MaxValue));
372  dataRow.SetValue(5, DataObject.Number(sequence.SequenceInfo.StartValue));
373  dataRow.SetValue(6, DataObject.BigInt(sequence.SequenceInfo.Cache));
374  dataRow.SetValue(7, DataObject.Boolean(sequence.SequenceInfo.Cycle));
375 
376  // Update the row
377  seq.UpdateRow(dataRow);
378  }
379 
380  public void Create() {
381  // SYSTEM.SEQUENCE_INFO
382  var tableInfo = new TableInfo(SystemSchema.SequenceInfoTableName);
383  tableInfo.AddColumn("id", PrimitiveTypes.Numeric());
384  tableInfo.AddColumn("schema", PrimitiveTypes.String());
385  tableInfo.AddColumn("name", PrimitiveTypes.String());
386  tableInfo.AddColumn("type", PrimitiveTypes.Numeric());
387  tableInfo = tableInfo.AsReadOnly();
388  Transaction.CreateTable(tableInfo);
389 
390  // SYSTEM.SEQUENCE
391  tableInfo = new TableInfo(SystemSchema.SequenceTableName);
392  tableInfo.AddColumn("seq_id", PrimitiveTypes.Numeric());
393  tableInfo.AddColumn("last_value", PrimitiveTypes.Numeric());
394  tableInfo.AddColumn("increment", PrimitiveTypes.Numeric());
395  tableInfo.AddColumn("minvalue", PrimitiveTypes.Numeric());
396  tableInfo.AddColumn("maxvalue", PrimitiveTypes.Numeric());
397  tableInfo.AddColumn("start", PrimitiveTypes.Numeric());
398  tableInfo.AddColumn("cache", PrimitiveTypes.Numeric());
399  tableInfo.AddColumn("cycle", PrimitiveTypes.Boolean());
400  tableInfo = tableInfo.AsReadOnly();
401  Transaction.CreateTable(tableInfo);
402  }
403 
405  var seqInfo = objInfo as SequenceInfo;
406  if (seqInfo == null)
407  throw new ArgumentException();
408 
409  CreateSequence(seqInfo);
410  }
411 
412  public ISequence CreateSequence(SequenceInfo sequenceInfo) {
413  if (sequenceInfo == null)
414  throw new ArgumentNullException("sequenceInfo");
415 
416  var sequenceName = sequenceInfo.SequenceName;
417 
418  // If the Sequence or SequenceInfo tables don't exist then
419  // We can't add or remove native tables
420  if (sequenceName.Equals(SystemSchema.SequenceTableName) ||
421  sequenceName.Equals(SystemSchema.SequenceInfoTableName) ||
424  return null;
425  }
426 
427  if (sequenceInfo.Type == SequenceType.Native)
428  return CreateNativeTableSequence(sequenceName);
429 
430  return CreateCustomSequence(sequenceName, sequenceInfo);
431  }
432 
433  private Sequence CreateCustomSequence(ObjectName sequenceName, SequenceInfo sequenceInfo) {
434  // The SEQUENCE and SEQUENCE_INFO table
435  var seq = Transaction.GetMutableTable(SystemSchema.SequenceTableName);
436  var seqi = Transaction.GetMutableTable(SystemSchema.SequenceInfoTableName);
437 
438  var list = seqi.SelectRowsEqual(2, DataObject.VarChar(sequenceName.Name), 1, DataObject.VarChar(sequenceName.Parent.FullName));
439  if (list.Any())
440  throw new Exception(String.Format("Sequence generator with name '{0}' already exists.", sequenceName));
441 
442  // Generate a unique id for the sequence info table
443  var uniqueId = Transaction.NextTableId(SystemSchema.SequenceInfoTableName);
444 
445  // Insert the new row
446  var dataRow = seqi.NewRow();
447  dataRow.SetValue(0, DataObject.Number(uniqueId));
448  dataRow.SetValue(1, DataObject.VarChar(sequenceName.Parent.FullName));
449  dataRow.SetValue(2, DataObject.VarChar(sequenceName.Name));
450  dataRow.SetValue(3, DataObject.BigInt(2));
451  seqi.AddRow(dataRow);
452 
453  // Insert into the SEQUENCE table.
454  dataRow = seq.NewRow();
455  dataRow.SetValue(0, DataObject.Number(uniqueId));
456  dataRow.SetValue(1, DataObject.Number(sequenceInfo.StartValue));
457  dataRow.SetValue(2, DataObject.Number(sequenceInfo.Increment));
458  dataRow.SetValue(3, DataObject.Number(sequenceInfo.MinValue));
459  dataRow.SetValue(4, DataObject.Number(sequenceInfo.MaxValue));
460  dataRow.SetValue(5, DataObject.Number(sequenceInfo.StartValue));
461  dataRow.SetValue(6, DataObject.BigInt(sequenceInfo.Cache));
462  dataRow.SetValue(7, DataObject.Boolean(sequenceInfo.Cycle));
463  seq.AddRow(dataRow);
464 
465  return new Sequence(this, uniqueId, sequenceInfo);
466  }
467 
469  var table = Transaction.GetMutableTable(SystemSchema.SequenceInfoTableName);
470  var uniqueId = Transaction.NextTableId(SystemSchema.SequenceInfoTableName);
471 
472  var dataRow = table.NewRow();
473  dataRow.SetValue(0, DataObject.Number(uniqueId));
474  dataRow.SetValue(1, DataObject.VarChar(tableName.Parent.FullName));
475  dataRow.SetValue(2, DataObject.VarChar(tableName.Name));
476  dataRow.SetValue(3, DataObject.BigInt(1));
477  table.AddRow(dataRow);
478 
479  return new Sequence(this, uniqueId, SequenceInfo.Native(tableName));
480  }
481 
483  throw new NotImplementedException();
484  }
485 
487  return DropSequence(objName);
488  }
489 
490  public ObjectName ResolveName(ObjectName objName, bool ignoreCase) {
491  throw new NotImplementedException();
492  }
493 
494  public bool DropSequence(ObjectName sequenceName) {
495  // If the Sequence or SequenceInfo tables don't exist then
496  // we can't create the sequence sequence
497  if (!Transaction.ObjectExists(SystemSchema.SequenceTableName) ||
499  throw new Exception("System sequence tables do not exist.");
500  }
501 
502  // Remove the table sequence (delete SEQUENCE_INFO and SEQUENCE entry)
503  return RemoveNativeTableSequence(sequenceName);
504  }
505 
506  private bool RemoveNativeTableSequence(ObjectName tableName) {
507  // If the Sequence or SequenceInfo tables don't exist then
508  // We can't add or remove native tables
509  if (tableName.Equals(SystemSchema.SequenceTableName) ||
511  !Transaction.ObjectExists(SystemSchema.SequenceTableName) ||
513  return false;
514  }
515 
516  // The SEQUENCE and SEQUENCE_INFO table
517  var seq = Transaction.GetMutableTable(SystemSchema.SequenceTableName);
518  var seqi = Transaction.GetMutableTable(SystemSchema.SequenceInfoTableName);
519 
520  var list = seqi.SelectRowsEqual(2, DataObject.VarChar(tableName.Name), 1, DataObject.VarChar(tableName.Parent.FullName));
521 
522  // Remove the corresponding entry in the SEQUENCE table
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) {
527  // Remove entry from the sequence table.
528  seq.RemoveRow(rowIndex2);
529  }
530 
531  // Remove entry from the sequence info table
532  seqi.RemoveRow(rowIndex);
533  }
534 
535  return true;
536  }
537 
539  return SequenceExists(objName);
540  }
541 
543  return SequenceExists(objName);
544  }
545 
546  public bool SequenceExists(ObjectName sequenceName) {
547  // If the Sequence or SequenceInfo tables don't exist then
548  // we can't create the sequence generator
549  if (!Transaction.TableExists(SystemSchema.SequenceTableName) ||
551  throw new Exception("System sequence tables do not exist.");
552  }
553 
554  // The SEQUENCE and SEQUENCE_INFO table
555  var seq = Transaction.GetMutableTable(SystemSchema.SequenceTableName);
556  var seqi = Transaction.GetMutableTable(SystemSchema.SequenceInfoTableName);
557 
558  return seqi.SelectRowsEqual(2, DataObject.VarChar(sequenceName.Parent.FullName), 1, DataObject.VarChar(sequenceName.Name)).Any();
559  }
560 
561 
563  lock (this) {
564  var sequence = (Sequence)GetSequence(name);
565 
566  if (sequence.SequenceInfo.Type == SequenceType.Native)
567  // Native generator
568  return Transaction.NextTableId(name);
569 
570  // Custom sequence generator
571  var currentVal = sequence.CurrentValue;
572 
573  // Increment the current value.
574  sequence.IncrementCurrentValue();
575 
576  // Have we reached the current cached point?
577  if (currentVal == sequence.LastValue) {
578  // Increment the generator
579  for (int i = 0; i < sequence.SequenceInfo.Cache; ++i) {
580  sequence.IncrementLastValue();
581  }
582 
583  // Update the state
584  UpdateSequenceState(sequence);
585 
586  }
587 
588  return sequence.CurrentValue;
589  }
590  }
591 
592  private SqlNumber SetValue(ObjectName name, SqlNumber value) {
593  lock (this) {
594  var sequence = (Sequence) GetSequence(name);
595 
596  if (sequence.SequenceInfo.Type == SequenceType.Native)
597  return Transaction.SetTableId(name, value);
598 
599  // Custom sequence generator
600  sequence.CurrentValue = value;
601  sequence.LastValue = value;
602 
603  // Update the state
604  UpdateSequenceState(sequence);
605 
606  return value;
607  }
608  }
609 
611  lock (this) {
612  var sequence = (Sequence) GetSequence(name);
613 
614  if (sequence.SequenceInfo.Type == SequenceType.Native)
615  return Transaction.NextTableId(name);
616 
617  // Custom sequence generator
618  return sequence.CurrentValue;
619  }
620  }
621 
623  return GetSequence(objName);
624  }
625 
626  public ISequence GetSequence(ObjectName sequenceName) {
627  // Is the generator already in the cache?
628  Sequence sequence;
629 
630  if (!sequenceKeyMap.TryGetValue(sequenceName, out sequence)) {
631  // This sequence generator is not in the cache so we need to query the
632  // sequence table for this.
633  var seqi = Transaction.GetTable(SystemSchema.SequenceInfoTableName);
634 
635  var schemaVal = DataObject.VarChar(sequenceName.Parent.FullName);
636  var nameVal = DataObject.VarChar(sequenceName.Name);
637  var list = seqi.SelectRowsEqual(2, nameVal, 1, schemaVal).ToList();
638 
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.");
643  }
644 
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);
650 
651  // Is this a custom sequence generator?
652  // (stype == 1) == true
653  if (stype.IsEqualTo(OneValue)) {
654  // Native generator.
655  sequence = new Sequence(this, (SqlNumber) sid.Value, SequenceInfo.Native(sequenceName));
656  } else {
657  // Query the sequence table.
658  var seq = Transaction.GetTable(SystemSchema.SequenceTableName);
659 
660  list = seq.SelectRowsEqual(0, sid).ToList();
661 
662  if (!list.Any())
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.");
666 
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();
675 
676  var info = new SequenceInfo(sequenceName, start, increment, minvalue, maxvalue, cache, cycle);
677  sequence = new Sequence(this, (SqlNumber) sid.Value, lastValue, info);
678 
679  // Put the generator in the cache
680  sequenceKeyMap[sequenceName] = sequence;
681  }
682 
683  }
684 
685  // Return the generator
686  return sequence;
687 
688  }
689 
690  #region Sequence
691 
692  class Sequence : ISequence {
693  private readonly SequenceManager manager;
694 
695  public Sequence(SequenceManager manager, SqlNumber id, SequenceInfo sequenceInfo)
696  : this(manager, id, SqlNumber.Null, sequenceInfo) {
697  }
698 
699  public Sequence(SequenceManager manager, SqlNumber id, SqlNumber lastValue, SequenceInfo sequenceInfo) {
700  this.manager = manager;
701  Id = id;
702  FullName = sequenceInfo.SequenceName;
703  SequenceInfo = sequenceInfo;
704  LastValue = lastValue;
705  CurrentValue = lastValue;
706  }
707 
708  public SqlNumber Id { get; private set; }
709 
710  public ObjectName FullName { get; private set; }
711 
713  get { return DbObjectType.Sequence; }
714  }
715 
716  public SequenceInfo SequenceInfo { get; private set; }
717 
718  public SqlNumber LastValue { get; set; }
719 
720  public SqlNumber CurrentValue { get; set; }
721 
723  return manager.GetCurrentValue(FullName);
724  }
725 
726  public SqlNumber NextValue() {
727  return manager.NextValue(FullName);
728  }
729 
730  public SqlNumber SetValue(SqlNumber value) {
731  return manager.SetValue(FullName, value);
732  }
733 
735  val += SequenceInfo.Increment;
736  if (val > SequenceInfo.MaxValue) {
737  if (SequenceInfo.Cycle) {
738  val = SequenceInfo.MinValue;
739  } else {
740  throw new InvalidOperationException("Sequence out of bounds.");
741  }
742  }
743  if (val < SequenceInfo.MinValue) {
744  if (SequenceInfo.Cycle) {
745  val = SequenceInfo.MaxValue;
746  } else {
747  throw new InvalidOperationException("Sequence out of bounds.");
748  }
749  }
750  return val;
751  }
752 
753  public void IncrementCurrentValue() {
754  CurrentValue = IncrementValue(CurrentValue);
755  }
756 
757  public void IncrementLastValue() {
758  LastValue = IncrementValue(LastValue);
759  }
760  }
761 
762  #endregion
763  }
764 }
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)
Definition: DataObject.cs:576
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.
Definition: ITable.cs:40
static ObjectName Parse(string s)
Parses the given string into a ObjectName object.
Definition: ObjectName.cs:139
bool ContainsTable(ObjectName name)
Checks if a table with the given name is contained in the current context.
override string ToString()
Definition: ObjectName.cs:225
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...
Definition: Transaction.cs:35
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()
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)
Definition: DataObject.cs:552
Represents a database object, such as a table, a trigger, a type or a column.
Definition: IDbObject.cs:24
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.
Definition: ObjectName.cs:44
static DataObject Boolean(SqlBoolean value)
Definition: DataObject.cs:544
override bool Equals(object obj)
Definition: ObjectName.cs:241
ISequence GetSequence(ObjectName sequenceName)
DataObject GetValue(long rowNumber, int columnOffset)
Gets a single cell within the table that is located at the given column offset and row...
ObjectName ResolveName(ObjectName objName, bool ignoreCase)
Normalizes the input object name using the case sensitivity specified.
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...
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.
Definition: SequenceInfo.cs:28
Provides the constant names of the types of tables in a database system.
Definition: TableTypes.cs:24
bool DropSequence(ObjectName sequenceName)
bool SequenceExists(ObjectName sequenceName)
Represents a dynamic object that encapsulates a defined SqlType and a compatible constant ISqlObject ...
Definition: DataObject.cs:35
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
Definition: IDbObject.cs:35
Provides utilities and properties for handling the SYSTEN schema of a database.
Definition: SystemSchema.cs:37
string FullName
Gets the full reference name formatted.
Definition: ObjectName.cs:114
DbObjectType ObjectType
Gets the type of objects managed by this instance.
static readonly ObjectName SequenceInfoTableName
void UpdateSequenceState(Sequence sequence)
Updates the state of the sequence key in the sequence tables in the database.
const string Sequence
Definition: TableTypes.cs:29
ObjectName Parent
Gets the parent reference of the current one, if any or null if none.
Definition: ObjectName.cs:99
SqlNumber MinValue
Gets the configured minimum value of the sequence.
static DataObject VarChar(string s)
Definition: DataObject.cs:622
Dictionary< ObjectName, Sequence > sequenceKeyMap
static DataObject BigInt(long value)
Definition: DataObject.cs:580
string Name
Gets the name of the object being referenced.
Definition: ObjectName.cs:108
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...
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.
Definition: ITransaction.cs:30
ISequence CreateNativeTableSequence(ObjectName tableName)
DbObjectType
The kind of objects that can be handled by a database system and its managers
Definition: DbObjectType.cs:27
Defines the metadata properties of a table existing within a database.
Definition: TableInfo.cs:41
int FindByName(ObjectName tableName)
Finds the index in this container of the given table by its name.
SequenceType
The form of a ISequence object in a transaction.
Definition: SequenceType.cs:26
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.
Definition: ISequence.cs:25