private void writeDenseIndex(Column column, DenseIndex index, int position) { FileStream fileStream = null; try { fileStream = new FileStream(Path, Database, $"{Name}-{column.IndexName}", FileType.Index); fileStream.Open(); // set position into index file fileStream.SetPosition(position); var temp = fileStream.CutToEnd(position); var headers = (int)DenseIndexFileSchemeSize.Count; var indexWeight = headers + index.Size + sizeof(byte); fileStream.SetPosition(position); fileStream.WriteByte(index.Removed); // write value fileStream.WriteBytes(index.Value); // write position into data file fileStream.WriteInt(index.RecordPosition); if (temp != null) { fileStream.WriteBytes(temp); } _logger.Trace($"Индекс записан."); // update index count in the begining of file fileStream.SetPosition(0); // read indexes count var count = fileStream.ReadInt(); fileStream.SetPosition(0); fileStream.WriteInt(++count); fileStream.Close(); } catch (Exception ex) { throw new Error($"{ex}"); } finally { // close fileStream?.Close(); } }
/// <summary> /// Insert values into table /// </summary> /// <param name="values"> Vlaues</param> /// <param name="hasPattern">flag for pattern</param> private void insert(IDictionary <string, string> values, bool hasPattern) { try { _fileStream = new FileStream(Path, Database, Name); _fileStream.Open(); // read last position and go there to insert new one _fileStream.SetPosition(0); var lastPosition = _fileStream.ReadInt(); _fileStream.SetPosition(lastPosition); // if patterned query #warning not released if (hasPattern) { throw new Exception("Method not released"); // for } else { var dataToInsert = values.ToList(); // compare count iserted data and column count if (dataToInsert.Count != Columns.Length) { throw new InsertCommandExcecute($"Inserted data does not match field count in table."); } //TODO: //only for the first column checking primary key auto increment /*if (Columns[0].AutoIncrement == 1) * { * dataToInsert.Insert(0, new KeyValuePair<string, string>("autoincrement", $"{}")); * }*/ // check data to insert for (int i = 0; i < Columns.Length; i++) { var isValid = checkDataToInsert(Columns[i].Name, dataToInsert[i].Value); if (!isValid) { throw new InsertCommandExcecute($"Column [{Columns[i].Name}] does not match for [{dataToInsert[i].Value}] format."); } } for (int i = 0; i < Columns.Length; i++) { switch (Columns[i].Type) { case 1: var numberValue = dataToInsert[i].Value; #if DEBUG numberValue = $"{Convert.ToInt32(Convert.ToDouble(numberValue))}"; #endif int intValue = Convert.ToInt32(numberValue); _fileStream.WriteInt(intValue); // if has index name write index if (Columns[i].IndexName?.Length > 0) { var newIndex = new DenseIndex(intValue, lastPosition); _logger.Trace($"Записываем индекс для колонки {Columns[i].Name} для значения {intValue}."); var posToInsertIndex = findPositiontoInsertIndex(Columns[i], intValue); writeDenseIndex(Columns[i], newIndex, posToInsertIndex); } break; case 2: byte byteValue = Convert.ToByte(dataToInsert[i].Value[0]); _fileStream.WriteByte(byteValue); break; case 3: // cut text without single quotes string text = dataToInsert[i].Value .Substring(1, dataToInsert[i].Value.Length - 2); // check available size if (text.Length > Columns[i].Size) { throw new InsertCommandExcecute($"Column [{Columns[i].Name}] has maximum size {Columns[i].Size}."); } // pad text if length is less then column size text = text.PadLeft((int)Columns[i].Size); _fileStream.WriteText(text); break; case 4: DateTime date; var dateString = dataToInsert[i].Value .Substring(1, dataToInsert[i].Value.Length - 2); var convertResult = DateTime.TryParse(dateString, out date); if (!convertResult) { throw new InsertCommandExcecute($"Value for column [{Columns[i].Name}] has not correct datetime format."); } _fileStream.WriteDate(date.Ticks); break; default: break; } } } // write last posistion var pos = (int)_fileStream.GetPosition(); _fileStream.SetPosition(0); _fileStream.WriteInt(pos); _fileStream.Close(); _fileStream = new FileStream(Path, Database, Name, FileType.Scheme); _fileStream.Open(); _fileStream.SetPosition(0); pos = _fileStream.ReadInt(); _fileStream.SetPosition(pos); _fileStream.WriteInt(lastPosition); _fileStream.SetPosition(0); _fileStream.WriteInt(pos + 4); _fileStream.Close(); } catch (Exception ex) { var msg = ex.Message; if (typeof(InsertCommandExcecute) == ex.GetType()) { throw ex as InsertCommandExcecute; } throw new Errors.Error(msg); } finally { // close _fileStream?.Close(); } }