Example #1
0
        /// <summary>
        /// Gets or sets specified data column value.
        /// </summary>
        /// <param name="columnIndex">Zero based column index.</param>
        /// <returns></returns>
        public object this[int columnIndex]
        {
            /* Fixed record structure:
             *      1 byte     - specified is row is used or free space
             *                   u - used
             *                   f - free space
             *      x bytes    - columns data
             *      2 bytes    - CRLF
             */

            get
            {
                if (columnIndex < 0)
                {
                    throw new Exception("The columnIndex can't be negative value !");
                }
                if (columnIndex > m_ColumnCount)
                {
                    throw new Exception("The columnIndex out of columns count !");
                }

                return(ConvertFromInternalData(m_ColumnDataTypes[columnIndex],
                                               m_RowData,
                                               m_ColumnDataStartOffsets[columnIndex],
                                               m_ColumnDataSizes[columnIndex]));
            }

            set
            {
                if (columnIndex < 0)
                {
                    throw new Exception("The columnIndex can't be negative value !");
                }
                if (columnIndex > m_ColumnCount)
                {
                    throw new Exception("The columnIndex out of columns count !");
                }

                byte[] val = LDB_Record.ConvertToInternalData(m_pOwnerDb.Columns[columnIndex], value);
                // Check that value won't exceed maximum cloumn allowed size
                if (val.Length > m_ColumnDataSizes[columnIndex])
                {
                    throw new Exception("Value exceeds maximum allowed value for column '" +
                                        m_pOwnerDb.Columns[columnIndex].ColumnName + "' !");
                }

                // TODO: String, string must be char(0) terminated and padded to column length
                if (m_ColumnDataTypes[columnIndex] == LDB_DataType.String)
                {
                    throw new Exception("TODO: String not implemented !");
                }

                // Update value in database file
                m_pOwnerDb.WriteToFile(m_Pointer + m_ColumnDataStartOffsets[columnIndex], val, 0, val.Length);

                // Update value in buffer
                Array.Copy(val, 0, m_RowData, m_ColumnDataStartOffsets[columnIndex], val.Length);
            }
        }
Example #2
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 #3
0
        /// <summary>
        /// Appends new record to table.
        /// </summary>
        public void AppendRecord(object[] values)
        {
            if (!IsDatabaseOpen)
            {
                throw new Exception("Database isn't open, please open database first !");
            }
            if (m_pColumns.Count != values.Length)
            {
                throw new Exception("Each column must have corresponding value !");
            }

            bool unlock = true;

            // Table is already locked, don't lock it
            if (TableLocked)
            {
                unlock = false;
            }
            else
            {
                LockTable(15);
            }

            // Construct record data
            byte[] record = LDB_Record.CreateRecord(this, values);

            // Get free data pages
            DataPage[] dataPages = GetDataPages(0,
                                                (int)
                                                Math.Ceiling(record.Length / (double)m_DataPageDataAreaSize));

            StoreDataToDataPages(m_DataPageDataAreaSize, record, dataPages);

            if (unlock)
            {
                UnlockTable();
            }
        }
Example #4
0
        /// <summary>
        /// Appends new record to table.
        /// </summary>
        public void AppendRecord(object[] values)
        {
            if (!IsDatabaseOpen)
            {
                throw new Exception("Database isn't open, please open database first !");
            }
            if (m_pColumns.Count != values.Length)
            {
                throw new Exception("Each column must have corresponding value !");
            }

            bool unlock = true;

            // Table is already locked, don't lock it
            if (TableLocked)
            {
                unlock = false;
            }
            else
            {
                LockTable(15);
            }

            /* Fixed record structure:
             *  1 byte     - specified is row is used or free space
             *               u - used
             *               f - free space
             *  x bytes    - columns data
             *  2 bytes    - CRLF
             */

            int rowLength = 1 + 2;

            for (int i = 0; i < m_pColumns.Count; i++)
            {
                rowLength += m_pColumns[i].ColumnSize;
            }

            int position = 1;

            byte[] record = new byte[rowLength];
            record[0]             = (int)'u';
            record[rowLength - 2] = (int)'\r';
            record[rowLength - 1] = (int)'\n';
            for (int i = 0; i < values.Length; i++)
            {
                byte[] columnData = LDB_Record.ConvertToInternalData(m_pColumns[i], values[i]);
                // Check that column won't exceed maximum length.
                if (columnData.Length > m_pColumns[i].ColumnSize)
                {
                    throw new Exception("Column '" + m_pColumns[i] + "' exceeds maximum value length !");
                }

                Array.Copy(columnData, 0, record, position, columnData.Length);
                position += columnData.Length;
            }

            // Find free row
            byte[] freeRowsBuffer = new byte[4];
            ReadFromFile(52, freeRowsBuffer, 0, freeRowsBuffer.Length);
            int freeRows = ldb_Utils.ByteToInt(freeRowsBuffer, 0);

            // There are plenty free rows, find first

            if (freeRows > 100)
            {
                //--- Find free record ---------------------------------------------------//
                long nextRowStartOffset = m_RowsStartOffset;
                long rowOffset          = 0;

                byte[] rowData = new byte[m_RowLength];
                while (true)
                {
                    ReadFromFile(nextRowStartOffset, rowData, 0, m_RowLength);

                    // We want used row
                    if (rowData[0] == 'f')
                    {
                        rowOffset = nextRowStartOffset;
                        break;
                    }

                    nextRowStartOffset += m_RowLength;
                }
                //-------------------------------------------------------------------------//

                // Write new record to file
                WriteToFile(rowOffset, record, 0, record.Length);

                // Update free rows count
                WriteToFile(52, ldb_Utils.IntToByte(freeRows - 1), 0, 4);
            }
            // There are few empty rows, just append it
            else
            {
                AppendToFile(record, 0, record.Length);
            }

            if (unlock)
            {
                UnlockTable();
            }
        }
Example #5
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;
        }