/// <summary> /// Default constructor. /// </summary> /// <param name="ownerDb">Table that owns this row.</param> /// <param name="rowStartDataPage">Data page on what row starts.</param> internal LDB_Record(DbFile ownerDb, DataPage rowStartDataPage) { m_pOwnerDb = ownerDb; m_pDataPage = rowStartDataPage; ParseRowInfo(); }
/// <summary> /// Creates record. Contains record info + record values. /// </summary> /// <param name="ownerDb">Roecord owner table.</param> /// <param name="rowValues">Row values what to store to record.</param> /// <returns></returns> internal static byte[] CreateRecord(DbFile ownerDb, object[] rowValues) { if (ownerDb.Columns.Count != rowValues.Length) { throw new Exception("LDB_Record.CreateRecord m_pOwnerDb.Columns.Count != rowValues.Length !"); } // Convert values to internal store format ArrayList rowByteValues = new ArrayList(); for (int i = 0; i < rowValues.Length; i++) { rowByteValues.Add(ConvertToInternalData(ownerDb.Columns[i], rowValues[i])); } /* RowInfo structure (4 bytes) * columnCount - holds column data data length xx bytes columns values */ MemoryStream msRecord = new MemoryStream(); // Write values sizes for (int i = 0; i < rowByteValues.Count; i++) { msRecord.Write(ldb_Utils.IntToByte(((byte[]) rowByteValues[i]).Length), 0, 4); } // Write values for (int i = 0; i < rowByteValues.Count; i++) { byte[] val = (byte[]) rowByteValues[i]; msRecord.Write(val, 0, val.Length); } return msRecord.ToArray(); }
/// <summary> /// Updates this record values. /// </summary> /// <param name="rowValues">Row new values.</param> private void UpdateRecord(object[] rowValues) { bool unlock = true; // Table is already locked, don't lock it if (m_pOwnerDb.TableLocked) { unlock = false; } else { m_pOwnerDb.LockTable(15); } // Create new record byte[] rowData = CreateRecord(m_pOwnerDb, rowValues); DataPage[] dataPages = DataPages; // Clear old data ?? do we need that // for(int i=0;i<dataPages.Length;i++){ // dataPages[i].Data = new byte[1000]; // } // We haven't enough room to store row, get needed data pages if ((int)Math.Ceiling(rowData.Length / (double)m_pOwnerDb.DataPageDataAreaSize) > dataPages.Length) { int dataPagesNeeded = (int)Math.Ceiling(rowData.Length / (double)m_pOwnerDb.DataPageDataAreaSize) - dataPages.Length; DataPage[] additionalDataPages = m_pOwnerDb.GetDataPages(dataPages[dataPages.Length - 1].Pointer, dataPagesNeeded); // Append new data pages to existing data pages chain dataPages[dataPages.Length - 1].NextDataPagePointer = additionalDataPages[0].Pointer; DataPage[] newVal = new DataPage[dataPages.Length + additionalDataPages.Length]; Array.Copy(dataPages, 0, newVal, 0, dataPages.Length); Array.Copy(additionalDataPages, 0, newVal, dataPages.Length, additionalDataPages.Length); dataPages = newVal; } // Store new record DbFile.StoreDataToDataPages(m_pOwnerDb.DataPageDataAreaSize, rowData, dataPages); // Update row info ParseRowInfo(); if (unlock) { m_pOwnerDb.UnlockTable(); } }
/// <summary> /// Default constructor. /// </summary> /// <param name="dataPageDataAreaSize">Specifies how much data data page can store.</param> /// <param name="ownerDB">Owner DB file..</param> /// <param name="startOffset">Data page start offset pointer.</param> public DataPage(int dataPageDataAreaSize, DbFile ownerDB, long startOffset) { /* DataPage structure * 2 bytes - CRLF * 1 byte - used (f - unused,u - used) * 8 byte - owner object id * 8 bytes - owner data page pointer * 8 bytes - continuing data page pointer * 4 bytes - stored data length in data area * 2 bytes - CRLF * 1000 bytes - data area */ m_DataAreaSize = dataPageDataAreaSize; m_pOwnerDB = ownerDB; m_StartPointer = startOffset; byte[] dataPageInfo = new byte[33]; ownerDB.SetFilePosition(startOffset); ownerDB.ReadFromFile(dataPageInfo, 0, dataPageInfo.Length); m_Data = new byte[dataPageDataAreaSize]; ownerDB.ReadFromFile(m_Data, 0, dataPageDataAreaSize); // CRLF if (dataPageInfo[0] != (byte)'\r') { throw new Exception( "Not right data page startOffset, or invalid data page <CR> is expected but is '" + (int)dataPageInfo[0] + "' !"); } if (dataPageInfo[1] != (byte)'\n') { throw new Exception( "Not right data page startOffset, or invalid data page <LF> is expected but is '" + (int)dataPageInfo[1] + "' !"); } // used if (dataPageInfo[2] == (byte)'u') { m_Used = true; } else { m_Used = false; } // owner object id m_OwnerID = ldb_Utils.ByteToLong(dataPageInfo, 3); // owner data page pointer m_OwnerDataPagePointer = ldb_Utils.ByteToLong(dataPageInfo, 11); // continuing data page pointer m_NextDataPagePointer = ldb_Utils.ByteToLong(dataPageInfo, 19); // stored data length in data area m_StoredDataLength = ldb_Utils.ByteToInt(dataPageInfo, 27); // CRLF if (dataPageInfo[31] != (byte)'\r') { throw new Exception( "Not right data page startOffset, or invalid data page <CR> is expected but is '" + (int)dataPageInfo[31] + "' !"); } if (dataPageInfo[32] != (byte)'\n') { throw new Exception( "Not right data page startOffset, or invalid data page <LF> is expected but is '" + (int)dataPageInfo[32] + "' !"); } }
/// <summary> /// Creates record. Contains record info + record values. /// </summary> /// <param name="ownerDb">Roecord owner table.</param> /// <param name="rowValues">Row values what to store to record.</param> /// <returns></returns> internal static byte[] CreateRecord(DbFile ownerDb, object[] rowValues) { if (ownerDb.Columns.Count != rowValues.Length) { throw new Exception("LDB_Record.CreateRecord m_pOwnerDb.Columns.Count != rowValues.Length !"); } // Convert values to internal store format ArrayList rowByteValues = new ArrayList(); for (int i = 0; i < rowValues.Length; i++) { rowByteValues.Add(ConvertToInternalData(ownerDb.Columns[i], rowValues[i])); } /* RowInfo structure (4 bytes) * columnCount - holds column data data length xx bytes columns values */ MemoryStream msRecord = new MemoryStream(); // Write values sizes for (int i = 0; i < rowByteValues.Count; i++) { msRecord.Write(ldb_Utils.IntToByte(((byte[]) rowByteValues[i]).Length), 0, 4); } // Write values for (int i = 0; i < rowByteValues.Count; i++) { byte[] val = (byte[]) rowByteValues[i]; msRecord.Write(val, 0, val.Length); } return msRecord.ToArray(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="ownerDb">Table that owns this row.</param> /// <param name="rowStartDataPage">Data page on what row starts.</param> internal LDB_Record(DbFile ownerDb, DataPage rowStartDataPage) { m_pOwnerDb = ownerDb; m_pDataPage = rowStartDataPage; ParseRowInfo(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="dataPageDataAreaSize">Specifies how much data data page can store.</param> /// <param name="ownerDB">Owner DB file..</param> /// <param name="startOffset">Data page start offset pointer.</param> public DataPage(int dataPageDataAreaSize, DbFile ownerDB, long startOffset) { /* DataPage structure 2 bytes - CRLF 1 byte - used (f - unused,u - used) 8 byte - owner object id 8 bytes - owner data page pointer 8 bytes - continuing data page pointer 4 bytes - stored data length in data area 2 bytes - CRLF 1000 bytes - data area */ m_DataAreaSize = dataPageDataAreaSize; m_pOwnerDB = ownerDB; m_StartPointer = startOffset; byte[] dataPageInfo = new byte[33]; ownerDB.SetFilePosition(startOffset); ownerDB.ReadFromFile(dataPageInfo, 0, dataPageInfo.Length); m_Data = new byte[dataPageDataAreaSize]; ownerDB.ReadFromFile(m_Data, 0, dataPageDataAreaSize); // CRLF if (dataPageInfo[0] != (byte) '\r') { throw new Exception( "Not right data page startOffset, or invalid data page <CR> is expected but is '" + (int) dataPageInfo[0] + "' !"); } if (dataPageInfo[1] != (byte) '\n') { throw new Exception( "Not right data page startOffset, or invalid data page <LF> is expected but is '" + (int) dataPageInfo[1] + "' !"); } // used if (dataPageInfo[2] == (byte) 'u') { m_Used = true; } else { m_Used = false; } // owner object id m_OwnerID = ldb_Utils.ByteToLong(dataPageInfo, 3); // owner data page pointer m_OwnerDataPagePointer = ldb_Utils.ByteToLong(dataPageInfo, 11); // continuing data page pointer m_NextDataPagePointer = ldb_Utils.ByteToLong(dataPageInfo, 19); // stored data length in data area m_StoredDataLength = ldb_Utils.ByteToInt(dataPageInfo, 27); // CRLF if (dataPageInfo[31] != (byte) '\r') { throw new Exception( "Not right data page startOffset, or invalid data page <CR> is expected but is '" + (int) dataPageInfo[31] + "' !"); } if (dataPageInfo[32] != (byte) '\n') { throw new Exception( "Not right data page startOffset, or invalid data page <LF> is expected but is '" + (int) dataPageInfo[32] + "' !"); } }