Example #1
0
        /// <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();
            }
        }
Example #2
0
        /// <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();
        }
Example #3
0
        /// <summary>
        /// Gets specified column data.
        /// </summary>
        /// <param name="columnIndex">Column index.</param>
        /// <returns></returns>
        private object GetColumnData(int columnIndex)
        {
            // Get column data start offset
            int columnStartOffset = 4*m_pOwnerDb.Columns.Count;
            for (int i = 0; i < columnIndex; i++)
            {
                columnStartOffset += m_ColumnValueSize[i];
            }

            int dataLength = m_ColumnValueSize[columnIndex];
            int startDataPage = (int) Math.Floor(columnStartOffset/(double) m_pOwnerDb.DataPageDataAreaSize);
            int offsetInStartDataPage = columnStartOffset - (startDataPage*m_pOwnerDb.DataPageDataAreaSize);

            int dataOffset = 0;
            int currentDataPageIndex = 0;
            byte[] columnData = new byte[dataLength];
            DataPage currentDataPage = DataPage;
            while (dataOffset < dataLength)
            {
                // We haven't reached to data page on what data starts, just go to next continuing data page
                if (currentDataPageIndex < startDataPage)
                {
                    // Get next continuing data page
                    currentDataPage = new DataPage(m_pOwnerDb.DataPageDataAreaSize,
                                                   m_pOwnerDb,
                                                   currentDataPage.NextDataPagePointer);
                    currentDataPageIndex++;
                }
                    // We need all this data page data + addtitional data pages data
                else if ((dataLength - dataOffset + offsetInStartDataPage) > currentDataPage.StoredDataLength)
                {
                    currentDataPage.ReadData(columnData,
                                             dataOffset,
                                             m_pOwnerDb.DataPageDataAreaSize - offsetInStartDataPage,
                                             offsetInStartDataPage);
                    dataOffset += m_pOwnerDb.DataPageDataAreaSize - offsetInStartDataPage;

                    // Get next continuing data page
                    currentDataPage = new DataPage(m_pOwnerDb.DataPageDataAreaSize,
                                                   m_pOwnerDb,
                                                   currentDataPage.NextDataPagePointer);
                    currentDataPageIndex++;

                    offsetInStartDataPage = 0;
                }
                    // This data page has all data we need
                else
                {
                    currentDataPage.ReadData(columnData,
                                             dataOffset,
                                             dataLength - dataOffset,
                                             offsetInStartDataPage);
                    dataOffset += dataLength - dataOffset;

                    offsetInStartDataPage = 0;
                }
            }

            // Convert to column data type
            return ConvertFromInternalData(m_pOwnerDb.Columns[columnIndex], columnData);
        }
Example #4
0
        /// <summary>
        /// Gets specified number of free data pages. If free data pages won't exist, creates new ones.
        /// Data pages are marked as used and OwnerDataPagePointer and NextDataPagePointer is set as needed.
        /// </summary>
        /// <param name="ownerDataPagePointer">Owner data page pointer that own first requested data page. If no owner then this value is 0.</param>
        /// <param name="count">Number of data pages wanted.</param>
        internal DataPage[] GetDataPages(long ownerDataPagePointer, int count)
        {
            if (!TableLocked)
            {
                throw new Exception("Table must be locked to acess GetDataPages() method !");
            }

            ArrayList freeDataPages = new ArrayList();

            // Get free data pages count from table header
            byte[] freeDataPagesCount = new byte[8];
            SetFilePosition(52);
            ReadFromFile(freeDataPagesCount, 0, freeDataPagesCount.Length);
            long nFreeDataPages = ldb_Utils.ByteToLong(freeDataPagesCount, 0);

            // We have plenty free data pages and enough for count requested, find requested count free data pages
            if (nFreeDataPages > 1000 && nFreeDataPages > count)
            {
                long nextDataPagePointer = m_DatapagesStartOffset + 1;
                while (freeDataPages.Count < count)
                {
                    DataPage dataPage = new DataPage(m_DataPageDataAreaSize, this, nextDataPagePointer);
                    if (!dataPage.Used)
                    {
                        dataPage.Used = true;
                        freeDataPages.Add(dataPage);
                    }

                    nextDataPagePointer += m_DataPageDataAreaSize + 33;
                }

                // Decrease free data pages count in table header
                SetFilePosition(52);
                ReadFromFile(ldb_Utils.LongToByte(nFreeDataPages - count), 0, 8);
            }
                // Just create new data pages
            else
            {
                for (int i = 0; i < count; i++)
                {
                    byte[] dataPage = DataPage.CreateDataPage(m_DataPageDataAreaSize,
                                                              true,
                                                              0,
                                                              0,
                                                              0,
                                                              new byte[m_DataPageDataAreaSize]);
                    GoToFileEnd();
                    long dataPageStartPointer = GetFilePosition();
                    WriteToFile(dataPage, 0, dataPage.Length);

                    freeDataPages.Add(new DataPage(m_DataPageDataAreaSize, this, dataPageStartPointer));
                }
            }

            // Relate data pages (chain)
            for (int i = 0; i < freeDataPages.Count; i++)
            {
                // First data page
                if (i == 0)
                {
                    // Owner data page poitner specified for first data page
                    if (ownerDataPagePointer > 0)
                    {
                        ((DataPage) freeDataPages[i]).OwnerDataPagePointer = ownerDataPagePointer;
                    }

                    // There is continuing data page
                    if (freeDataPages.Count > 1)
                    {
                        ((DataPage) freeDataPages[i]).NextDataPagePointer =
                            ((DataPage) freeDataPages[i + 1]).Pointer;
                    }
                }
                    // Last data page
                else if (i == (freeDataPages.Count - 1))
                {
                    ((DataPage) freeDataPages[i]).OwnerDataPagePointer =
                        ((DataPage) freeDataPages[i - 1]).Pointer;
                }
                    // Middle range data page
                else
                {
                    ((DataPage) freeDataPages[i]).OwnerDataPagePointer =
                        ((DataPage) freeDataPages[i - 1]).Pointer;
                    ((DataPage) freeDataPages[i]).NextDataPagePointer =
                        ((DataPage) freeDataPages[i + 1]).Pointer;
                }
            }

            DataPage[] retVal = new DataPage[freeDataPages.Count];
            freeDataPages.CopyTo(retVal);

            return retVal;
        }
Example #5
0
        /// <summary>
        /// Stores data to specified data pages.
        /// </summary>
        /// <param name="dataPageDataAreaSize">Data page data area size.</param>
        /// <param name="data">Data to store.</param>
        /// <param name="dataPages">Data pages where to store data.</param>
        internal static void StoreDataToDataPages(int dataPageDataAreaSize, byte[] data, DataPage[] dataPages)
        {
            if ((int) Math.Ceiling(data.Length/(double) dataPageDataAreaSize) > dataPages.Length)
            {
                throw new Exception("There isn't enough data pages to store data ! Data needs '" +
                                    (int) Math.Ceiling(data.Length/(double) dataPageDataAreaSize) +
                                    "' , but available '" + dataPages.Length + "'.");
            }

            //--- Store data to data page(s) -----------------------//
            long position = 0;
            for (int i = 0; i < dataPages.Length; i++)
            {
                if ((data.Length - position) > dataPageDataAreaSize)
                {
                    byte[] d = new byte[dataPageDataAreaSize];
                    Array.Copy(data, position, d, 0, d.Length);
                    dataPages[i].WriteData(d);
                    position += dataPageDataAreaSize;
                }
                else
                {
                    byte[] d = new byte[data.Length - position];
                    Array.Copy(data, position, d, 0, d.Length);
                    dataPages[i].WriteData(d);
                }
            }
            //------------------------------------------------------//	
        }
Example #6
0
        /*
		/// <summary>
		/// Locks current record.
		/// </summary>
		public void LockRecord()
		{
			if(!this.IsDatabaseOpen){
				throw new Exception("Database isn't open, please open database first !");
			}

		}
*/

        /*
		/// <summary>
		/// Unlocks current record.
		/// </summary>
		public void UnlockRecord()
		{
			if(!this.IsDatabaseOpen){
				throw new Exception("Database isn't open, please open database first !");
			}

		}
*/

        /// <summary>
        /// Gets next record. Returns true if end of file reached and there are no more records.
        /// </summary>
        /// <returns>Returns true if end of file reached and there are no more records.</returns>
        public bool NextRecord()
        {
            if (!IsDatabaseOpen)
            {
                throw new Exception("Database isn't open, please open database first !");
            }

            //--- Find next record ---------------------------------------------------//
            long nextRowStartOffset = 0;
            if (m_pCurrentRecord == null)
            {
                nextRowStartOffset = m_DatapagesStartOffset;
            }
            else
            {
                nextRowStartOffset = m_pCurrentRecord.DataPage.Pointer + m_DataPageDataAreaSize + 33;
            }

            while (true)
            {
                if (m_FileLength > nextRowStartOffset)
                {
                    DataPage dataPage = new DataPage(m_DataPageDataAreaSize, this, nextRowStartOffset);

                    // We want datapage with used space
                    if (dataPage.Used && dataPage.OwnerDataPagePointer < 1)
                    {
                        m_pCurrentRecord = new LDB_Record(this, dataPage);
                        break;
                    }
                }
                else
                {
                    return true;
                }

                nextRowStartOffset += m_DataPageDataAreaSize + 33;
            }
            //-------------------------------------------------------------------------//

            return false;
        }
Example #7
0
        /// <summary>
        /// Gets specified column data.
        /// </summary>
        /// <param name="columnIndex">Column index.</param>
        /// <returns></returns>
        private object GetColumnData(int columnIndex)
        {
            // Get column data start offset
            int columnStartOffset = 4 * m_pOwnerDb.Columns.Count;

            for (int i = 0; i < columnIndex; i++)
            {
                columnStartOffset += m_ColumnValueSize[i];
            }

            int dataLength            = m_ColumnValueSize[columnIndex];
            int startDataPage         = (int)Math.Floor(columnStartOffset / (double)m_pOwnerDb.DataPageDataAreaSize);
            int offsetInStartDataPage = columnStartOffset - (startDataPage * m_pOwnerDb.DataPageDataAreaSize);

            int dataOffset           = 0;
            int currentDataPageIndex = 0;

            byte[]   columnData      = new byte[dataLength];
            DataPage currentDataPage = DataPage;

            while (dataOffset < dataLength)
            {
                // We haven't reached to data page on what data starts, just go to next continuing data page
                if (currentDataPageIndex < startDataPage)
                {
                    // Get next continuing data page
                    currentDataPage = new DataPage(m_pOwnerDb.DataPageDataAreaSize,
                                                   m_pOwnerDb,
                                                   currentDataPage.NextDataPagePointer);
                    currentDataPageIndex++;
                }
                // We need all this data page data + addtitional data pages data
                else if ((dataLength - dataOffset + offsetInStartDataPage) > currentDataPage.StoredDataLength)
                {
                    currentDataPage.ReadData(columnData,
                                             dataOffset,
                                             m_pOwnerDb.DataPageDataAreaSize - offsetInStartDataPage,
                                             offsetInStartDataPage);
                    dataOffset += m_pOwnerDb.DataPageDataAreaSize - offsetInStartDataPage;

                    // Get next continuing data page
                    currentDataPage = new DataPage(m_pOwnerDb.DataPageDataAreaSize,
                                                   m_pOwnerDb,
                                                   currentDataPage.NextDataPagePointer);
                    currentDataPageIndex++;

                    offsetInStartDataPage = 0;
                }
                // This data page has all data we need
                else
                {
                    currentDataPage.ReadData(columnData,
                                             dataOffset,
                                             dataLength - dataOffset,
                                             offsetInStartDataPage);
                    dataOffset += dataLength - dataOffset;

                    offsetInStartDataPage = 0;
                }
            }

            // Convert to column data type
            return(ConvertFromInternalData(m_pOwnerDb.Columns[columnIndex], columnData));
        }
Example #8
0
        /// <summary>
        /// Gets specified number of free data pages. If free data pages won't exist, creates new ones.
        /// Data pages are marked as used and OwnerDataPagePointer and NextDataPagePointer is set as needed.
        /// </summary>
        /// <param name="ownerDataPagePointer">Owner data page pointer that own first requested data page. If no owner then this value is 0.</param>
        /// <param name="count">Number of data pages wanted.</param>
        internal DataPage[] GetDataPages(long ownerDataPagePointer, int count)
        {
            if (!TableLocked)
            {
                throw new Exception("Table must be locked to acess GetDataPages() method !");
            }

            ArrayList freeDataPages = new ArrayList();

            // Get free data pages count from table header
            byte[] freeDataPagesCount = new byte[8];
            SetFilePosition(52);
            ReadFromFile(freeDataPagesCount, 0, freeDataPagesCount.Length);
            long nFreeDataPages = ldb_Utils.ByteToLong(freeDataPagesCount, 0);

            // We have plenty free data pages and enough for count requested, find requested count free data pages
            if (nFreeDataPages > 1000 && nFreeDataPages > count)
            {
                long nextDataPagePointer = m_DatapagesStartOffset + 1;
                while (freeDataPages.Count < count)
                {
                    DataPage dataPage = new DataPage(m_DataPageDataAreaSize, this, nextDataPagePointer);
                    if (!dataPage.Used)
                    {
                        dataPage.Used = true;
                        freeDataPages.Add(dataPage);
                    }

                    nextDataPagePointer += m_DataPageDataAreaSize + 33;
                }

                // Decrease free data pages count in table header
                SetFilePosition(52);
                ReadFromFile(ldb_Utils.LongToByte(nFreeDataPages - count), 0, 8);
            }
            // Just create new data pages
            else
            {
                for (int i = 0; i < count; i++)
                {
                    byte[] dataPage = DataPage.CreateDataPage(m_DataPageDataAreaSize,
                                                              true,
                                                              0,
                                                              0,
                                                              0,
                                                              new byte[m_DataPageDataAreaSize]);
                    GoToFileEnd();
                    long dataPageStartPointer = GetFilePosition();
                    WriteToFile(dataPage, 0, dataPage.Length);

                    freeDataPages.Add(new DataPage(m_DataPageDataAreaSize, this, dataPageStartPointer));
                }
            }

            // Relate data pages (chain)
            for (int i = 0; i < freeDataPages.Count; i++)
            {
                // First data page
                if (i == 0)
                {
                    // Owner data page poitner specified for first data page
                    if (ownerDataPagePointer > 0)
                    {
                        ((DataPage)freeDataPages[i]).OwnerDataPagePointer = ownerDataPagePointer;
                    }

                    // There is continuing data page
                    if (freeDataPages.Count > 1)
                    {
                        ((DataPage)freeDataPages[i]).NextDataPagePointer =
                            ((DataPage)freeDataPages[i + 1]).Pointer;
                    }
                }
                // Last data page
                else if (i == (freeDataPages.Count - 1))
                {
                    ((DataPage)freeDataPages[i]).OwnerDataPagePointer =
                        ((DataPage)freeDataPages[i - 1]).Pointer;
                }
                // Middle range data page
                else
                {
                    ((DataPage)freeDataPages[i]).OwnerDataPagePointer =
                        ((DataPage)freeDataPages[i - 1]).Pointer;
                    ((DataPage)freeDataPages[i]).NextDataPagePointer =
                        ((DataPage)freeDataPages[i + 1]).Pointer;
                }
            }

            DataPage[] retVal = new DataPage[freeDataPages.Count];
            freeDataPages.CopyTo(retVal);

            return(retVal);
        }