{*
 *******************************************************************************
 *
 *  Copyright 2026 RIEGL Laser Measurement Systems
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  SPDX-License-Identifier: Apache-2.0
 *
 *******************************************************************************
 *}
{*!
 *******************************************************************************
 *
 * \file    riegl.rdb.error.pas
 * \author  RIEGL LMS GmbH, Austria
 * \brief   Database error signaling/handling (Pascal wrapper code)
 * \version 2015-10-14/AW: Initial version
 * \version 2017-11-09/AW: Error 'PointAttributeNotMergeable' added
 * \version 2018-03-12/AW: Error 'PointAttributeInvalidInvalid' added (#3047)
 * \version 2018-11-20/AW: Error 'QueryInsertTooManyPoints' added (#3215)
 * \version 2019-05-13/AW: Error 'MetadataInvalidName' added
 * \version 2020-02-14/AW: Error 'MetadataTableTooLarge' added (#3560)
 * \version 2020-03-30/AW: Error 'MetadataSignatureError' added (#3570)
 * \version 2021-06-02/AW: Error 'TransactionDetailsTooLarge' added (#3905)
 * \version 2021-06-02/AW: Error 'InvalidStringSize' added (#3905)
 * \version 2024-11-26/AW: Error 'QueryInsertFailed' added (#5339)
 *
 *******************************************************************************
 *}

unit riegl.rdb.error;

{******************************************************************************}
{***} INTERFACE {**************************************************************}
{******************************************************************************}

//---< INCLUDES >---------------------------------------------------------------

uses
  SysUtils;

//---< CLASS ERDBError >--------------------------------------------------------
{*!
 * \brief Database error class
 *}
type
  ERDBError = class(SysUtils.Exception)
  private
    FCode    : System.Longint;
    FDetails : System.String;

    function GetCode    : System.Longint;
    function GetText    : System.String;
    function GetDetails : System.String;

  public
    constructor Create(
      const Code    : System.Longint;
      const Text    : System.String;
      const Details : System.String
    );

    property Code    : System.Longint read GetCode;
    property Text    : System.String  read GetText;
    property Details : System.String  read GetDetails;
  end;

//---< ERROR CODES >------------------------------------------------------------

const RDBErrorDatabaseOpenFailed              = 10100; //!< failed to create or open database, most likely insufficient access rights or invalid location
const RDBErrorDatabaseNotOpened               = 10101; //!< a query failed because no database was opened
const RDBErrorDatabaseNotWritable             = 10102; //!< modification of database not possible as opened in read-only mode (check file access rights)
const RDBErrorDatabaseVersionNotSupported     = 10103; //!< database file format version not supported
const RDBErrorDatabaseSchemaValidationFailed  = 10104; //!< database does not correspond to user-supplied schema
//
const RDBErrorTransactionMissing              = 10201; //!< operation failed because there was no transaction, see pointcloud::Transactions::begin()
const RDBErrorTransactionPending              = 10202; //!< operation failed because a transaction is started but not yet finished
const RDBErrorTransactionCorrupted            = 10203; //!< operation failed because database was modified by concurrent client (should never happen)
const RDBErrorTransactionInvalid              = 10204; //!< given transaction ID is invalid
const RDBErrorTransactionLockAcquireFailed    = 10205; //!< failed to acquire database transaction lock
const RDBErrorTransactionLockReleaseFailed    = 10206; //!< failed to release database transaction lock
const RDBErrorTransactionDetailsTooLarge      = 10207; //!< total size of all transaction details strings exceeds the limit
//
const RDBErrorPointAttributeDuplicate         = 10301; //!< point attribute of given name already exists
const RDBErrorPointAttributeMissing           = 10302; //!< point attribute of given name does not exist, attribute name is stored in error details
const RDBErrorPointAttributeInvalidLength     = 10303; //!< point attribute vector length is invalid
const RDBErrorPointAttributeInvalidLimits     = 10304; //!< point attribute minimum and maximum are invalid
const RDBErrorPointAttributeInvalidDefault    = 10305; //!< point attribute default value out of range (min./max.)
const RDBErrorPointAttributeInvalidResolution = 10306; //!< point attribute resolution is invalid
const RDBErrorPointAttributeCannotDuplicate   = 10307; //!< source point attribute data could not be copied to target point attribute data as they are not compatible
const RDBErrorPointAttributeCannotModify      = 10308; //!< modification of point attribute property not allowed (property name is stored in error details)
const RDBErrorPointAttributeInvalidScale      = 10309; //!< invalid point attribute scale factor given (value is stored in error details)
const RDBErrorPointAttributeNotMergeable      = 10310; //!< the point attribute details can not be merged because they are not compatible (reason see details) \see riegl::rdb::pointcloud::PointAttributes::getMerged()
const RDBErrorPointAttributeInvalidInvalid    = 10311; //!< point attribute invalid value out of range (min./max.)
//
const RDBErrorMetadataValidationFailed        = 10312; //!< metadata entry does not correspond to schema
const RDBErrorMetadataInvalidName             = 10313; //!< metadata entry name is not allowed (name is stored in error details)
const RDBErrorMetadataTableTooLarge           = 10314; //!< total size of all metadata item names and values exceeds the limit
const RDBErrorMetadataSignatureError          = 10315; //!< failed to create or verify metadata entry signature (reason in error details)
//
const RDBErrorQueryBindAttributeInvalid       = 10401; //!< bound invalid attribute to query, attribute name is stored in error details (not all attributes are allowed in all queries)
const RDBErrorQueryBindAttributeUnknown       = 10402; //!< bound unknown attribute to query, attribute name is stored in error details
const RDBErrorQueryBindAttributeIndexVoid     = 10403; //!< bound attribute with invalid vector index
const RDBErrorQueryBindAttributeBufferVoid    = 10404; //!< bound attribute buffer is invalid
const RDBErrorQuerySelectFilterParseFailed    = 10406; //!< select query filter string parsing failed, check syntax
const RDBErrorQuerySelectAttributeUnknown     = 10407; //!< select query filter string refers to unknown point attribute, attribute name is stored in error details
const RDBErrorQuerySelectVectorIndexMissing   = 10408; //!< select query filter string does not define vector index for vector point attribute
const RDBErrorQuerySelectVectorIndexInvalid   = 10409; //!< select query filter string contains invalid vector attribute index
const RDBErrorQuerySelectGraphNodeInvalid     = 10410; //!< select query node ID invalid
const RDBErrorQueryInsertNoPrimaryAttribute   = 10411; //!< no buffer for primary point attribute defined
const RDBErrorQueryUpdateConstantAttribute    = 10412; //!< tried to modify a constant attribute
const RDBErrorQueryStatIndexNodeNotFound      = 10413; //!< index graph node not found (invalid node ID)
const RDBErrorQueryAttributeValueOutOfRange   = 10414; //!< given attribute value (insert or update) is out of range, attribute name is stored in error details
const RDBErrorQueryPointIdentifierMissing     = 10415; //!< no buffer for point ID attribute defined
const RDBErrorQueryPending                    = 10416; //!< can't start a new query as an other query started by this Pointcloud instance is not finished yet
const RDBErrorQueryBindAttributeIncomplete    = 10417; //!< no buffer given for at least one element of an vector point attribute (i.e. when length > 1)
const RDBErrorQueryInsertTooManyPoints        = 10418; //!< points can not be inserted as the total number of points would exceed the limit of 65536 * points-per-chunk (defined at database creation); this limit only applies if the primary point attribute is "riegl.id" (point ID)
const RDBErrorQueryInsertFailed               = 10419; //!< point insertion query failed, check the error details for the reason
//
const RDBErrorFeatureNotLicensed              = 10001; //!< no valid license key found for requested feature
const RDBErrorFailedToParseJSON               = 10002; //!< failed to parse JSON string, reason available in error details
const RDBErrorInvalidStringSize               = 10003; //!< invalid string size, string name and limit in error details
const RDBErrorInternal                        = 90000; //!< base error code for fatal internal errors
const RDBErrorUnknown                         =     1; //!< unknown error occurred

{******************************************************************************}
{***} IMPLEMENTATION {*********************************************************}
{******************************************************************************}

//---< ERDBError::PUBLIC >------------------------------------------------------

constructor ERDBError.Create(
  const Code    : System.Longint;
  const Text    : System.String;
  const Details : System.String
);
begin
  inherited Create(Text);
  Self.FCode    := Code;
  Self.FDetails := Details;
end;

//---< ERDBError::PRIVATE >-----------------------------------------------------

function ERDBError.GetCode : System.Longint;
begin
  Result := Self.FCode;
end;

function ERDBError.GetText : System.String;
begin
  Result := Self.Message;
end;

function ERDBError.GetDetails : System.String;
begin
  Result := Self.FDetails;
end;

end.
