/EffiProz-CF/Core/TextTable.cs
C# | 438 lines | 258 code | 90 blank | 90 comment | 41 complexity | 23926fad1cc6a0c71dcc065a1d0fa613 MD5 | raw file
Possible License(s): BSD-3-Clause
- //
- // (C) Copyright 2009 Irantha Suwandarathna (irantha@gmail.com)
- // All rights reserved.
- //
-
- /* Copyright (c) 2001-2008, The HSQL Development Group
- * All rights reserved.
- *
- * Redistribution and use _in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions _in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer _in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the HSQL Development Group nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Linq;
- using System.Reflection;
- using System.IO;
- using EffiProz.Core.Lib;
- using EffiProz.Core.ScriptIO;
- using EffiProz.Core.Persist;
- using EffiProz.Core.Errors;
-
-
-
- namespace EffiProz.Core
- {
-
- // tony_lai@users 20020820 - patch 595099 - user define PK name
-
- /**
- * Subclass of Table to handle TEXT data source. <p>
- *
- *:Table to provide the notion of an SQL base table object whose
- * data is read from and written to a text format data file.
- *
- * @author sqlbob@users (RMP)
- * @version 1.8.0
- */
- public class TextTable : Table
- {
-
- private String dataSource = "";
- private bool isReversed = false;
- private bool _isConnected = false;
-
- // TextCache cache;
-
- /**
- * Constructs a new TextTable from the given arguments.
- *
- * @param db the owning database
- * @param name the table's HsqlName
- * @param type code (normal or temp text table)
- */
- public TextTable(Database db, QNameManager.QName name, int type)
- : base(db, name, type)
- {
-
- }
-
- public bool isConnected()
- {
- return _isConnected;
- }
-
- /**
- * connects to the data source
- */
- public void connect(Session session)
- {
- connect(session, _isReadOnly);
- }
-
- /**
- * connects to the data source
- */
- private void connect(Session session, bool withReadOnlyData)
- {
-
- // Open new cache:
- if ((dataSource.Length == 0) || _isConnected)
- {
-
- // nothing to do
- return;
- }
-
- PersistentStore store =
- database.persistentStoreCollection.getStore(this);
-
- this.store = store;
-
- DataFileCache cache = null;
-
- try
- {
- cache = (TextCache)database.logger.openTextFilePersistence(this,
- dataSource, withReadOnlyData, isReversed);
-
- store.setCache(cache);
-
- // read and insert all the rows from the source file
- Row row = null;
- int nextpos = 0;
-
- if (((TextCache)cache).ignoreFirst)
- {
- nextpos += ((TextCache)cache).readHeaderLine();
- }
-
- while (true)
- {
- row = (Row)store.get(nextpos, false);
-
- if (row == null)
- {
- break;
- }
-
- Object[] data = row.getData();
-
- nextpos = row.getPos() + row.getStorageSize();
-
- ((RowAVLDiskData)row).setNewNodes();
- systemUpdateIdentityValue(data);
- enforceRowConstraints(session, data);
-
- for (int i = 0; i < indexList.Length; i++)
- {
- indexList[i].insert(null, store, row);
- }
- }
- }
- catch (Exception t)
- {
- int linenumber = cache == null ? 0
- : ((TextCache)cache)
- .getLineNumber();
-
- clearAllData(session);
-
- if (cache != null)
- {
- database.logger.closeTextCache(this);
- store.release();
- }
-
- // everything is in order here.
- // At this point table should either have a valid (old) data
- // source and cache or have an empty source and null cache.
- throw Error.error(t, ErrorCode.TEXT_FILE, 0, new Object[] {
- t.Message, linenumber
- });
- }
-
- _isConnected = true;
- _isReadOnly = withReadOnlyData;
- }
-
- /**
- * disconnects from the data source
- */
- public void disconnect()
- {
-
- this.store = null;
-
- PersistentStore store =
- database.persistentStoreCollection.getStore(this);
-
- store.release();
-
- _isConnected = false;
- }
-
- /**
- * This method does some of the work involved with managing the creation
- * and openning of the cache, the rest is done in Log.java and
- * TextCache.java.
- *
- * Better clarification of the role of the methods is needed.
- */
- private void openCache(Session session, String dataSourceNew,
- bool isReversedNew, bool isReadOnlyNew)
- {
-
- String dataSourceOld = dataSource;
- bool isReversedOld = isReversed;
- bool isReadOnlyOld = _isReadOnly;
-
- if (dataSourceNew == null)
- {
- dataSourceNew = "";
- }
-
- disconnect();
-
- dataSource = dataSourceNew;
- isReversed = (isReversedNew && dataSource.Length > 0);
-
- try
- {
- connect(session, isReadOnlyNew);
- }
- catch (CoreException e)
- {
- dataSource = dataSourceOld;
- isReversed = isReversedOld;
-
- connect(session, isReadOnlyOld);
-
- throw e;
- }
- }
-
- /**
- * High level command to assign a data source to the table definition.
- * Reassigns only if the data source or direction has changed.
- */
- public void setDataSource(Session session, String dataSourceNew,
- bool isReversedNew, bool createFile)
- {
-
- if (getTableType() == Table.TEMP_TEXT_TABLE)
- {
- ;
- }
- else
- {
- session.getGrantee().checkSchemaUpdateOrGrantRights(
- getSchemaName().name);
- }
-
- dataSourceNew = dataSourceNew.Trim();
-
- if (createFile && FileUtil.GetDefaultInstance().exists(dataSourceNew))
- {
- throw Error.error(ErrorCode.TEXT_SOURCE_EXISTS, dataSourceNew);
- }
-
- //-- Open if descending, direction changed, file changed, or not connected currently
- if (isReversedNew || (isReversedNew != isReversed)
- || !dataSource.Equals(dataSourceNew) || !_isConnected)
- {
- openCache(session, dataSourceNew, isReversedNew, _isReadOnly);
- }
-
- if (isReversed)
- {
- _isReadOnly = true;
- }
- }
-
- public String getDataSource()
- {
- return dataSource;
- }
-
- public bool isDescDataSource()
- {
- return isReversed;
- }
-
- public void setHeader(String header)
- {
-
- PersistentStore store =
- database.persistentStoreCollection.getStore(this);
- TextCache cache = (TextCache)store.getCache();
-
- if (cache != null && cache.ignoreFirst)
- {
- cache.setHeader(header);
-
- return;
- }
-
- throw Error.error(ErrorCode.TEXT_TABLE_HEADER);
- }
-
- public String getHeader()
- {
-
- PersistentStore store =
- database.persistentStoreCollection.getStore(this);
- TextCache cache = (TextCache)store.getCache();
- String header = cache == null ? null
- : cache.getHeader();
-
- return header == null ? null
- : StringConverter.toQuotedString(header, '\'',
- true);
- }
-
- /**
- * Used by INSERT, DELETE, UPDATE operations. This class will return
- * a more appropriate message when there is no data source.
- */
- public override void checkDataReadOnly()
- {
-
- if (dataSource.Length == 0)
- {
- throw Error.error(ErrorCode.TEXT_TABLE_UNKNOWN_DATA_SOURCE);
- }
-
- if (_isReadOnly)
- {
- throw Error.error(ErrorCode.DATA_IS_READONLY);
- }
- }
-
- public override bool isDataReadOnly()
- {
- return !isConnected() || base.isDataReadOnly() ||
- store.getCache().isDataReadOnly();
- }
-
- public override void setDataReadOnly(bool value)
- {
-
- if (!value)
- {
- if (isReversed)
- {
- throw Error.error(ErrorCode.DATA_IS_READONLY);
- }
-
- if (database.isFilesReadOnly())
- {
- throw Error.error(ErrorCode.DATABASE_IS_READONLY);
- }
- }
-
- _isReadOnly = value;
- }
-
- public override bool isIndexCached()
- {
- return false;
- }
-
- public void setIndexRoots(String s)
- {
-
- // do nothing
- }
-
- public String getDataSourceDDL()
- {
-
- String dataSource = getDataSource();
-
- if (dataSource == null)
- {
- return null;
- }
-
- bool isDesc = isDescDataSource();
- StringBuilder sb = new StringBuilder(128);
-
- sb.Append(Tokens.T_SET).Append(' ').Append(Tokens.T_TABLE).Append(' ');
- sb.Append(getName().getSchemaQualifiedStatementName());
- sb.Append(' ').Append(Tokens.T_SOURCE).Append(' ').Append('\'');
- sb.Append(dataSource);
- sb.Append('\'');
-
- if (isDesc)
- {
- sb.Append(' ').Append(Tokens.T_DESC);
- }
-
- return sb.ToString();
- }
-
- /**
- * Generates the SET TABLE <tablename> SOURCE HEADER <string> statement for a
- * text table;
- */
- public String getDataSourceHeader()
- {
-
- String header = getHeader();
-
- if (header == null)
- {
- return null;
- }
-
- StringBuilder sb = new StringBuilder(128);
-
- sb.Append(Tokens.T_SET).Append(' ').Append(Tokens.T_TABLE).Append(' ');
- sb.Append(getName().getSchemaQualifiedStatementName());
- sb.Append(' ').Append(Tokens.T_SOURCE).Append(' ');
- sb.Append(Tokens.T_HEADER).Append(' ');
- sb.Append(header);
-
- return sb.ToString();
- }
-
- /**
- * Adds commitPersistence() call
- */
- public override void insertData(PersistentStore store, Object[] data)
- {
-
- Row row = (Row)store.getNewCachedObject(null, data);
-
- store.indexRow(null, row);
- store.commitPersistence(row);
- }
- }
- }