code: package it.unibz.inf.ontop.model.term.functionsymbol.db;
  
  import com.google.common.collect.ImmutableList;
  import it.unibz.inf.ontop.model.template.Template;
  import it.unibz.inf.ontop.model.term.ImmutableTerm;
  import it.unibz.inf.ontop.model.term.functionsymbol.FunctionSymbol;
  import it.unibz.inf.ontop.model.term.functionsymbol.InequalityLabel;
  import it.unibz.inf.ontop.model.type.DBTermType;
  import it.unibz.inf.ontop.model.type.RDFTermType;
  import org.apache.commons.rdf.api.IRI;
  
  import java.util.Optional;
  import java.util.UUID;
  
  
  /**
   * Factory for DBFunctionSymbols
   *
   * Accessible through Guice (recommended) or through CoreSingletons.
   */
  public interface DBFunctionSymbolFactory {
  
      /**
       * NB: a functional term using this symbol is producing a NULL or a DB string
       */
      IRIStringTemplateFunctionSymbol getIRIStringTemplateFunctionSymbol(ImmutableList<Template.Component> iriTemplate);
  
      /**
       * NB: a functional term using this symbol is producing a NULL or a DB string
       */
      BnodeStringTemplateFunctionSymbol getBnodeStringTemplateFunctionSymbol(ImmutableList<Template.Component> bnodeTemplate);
  
      /**
       * Returns a fresh Bnode template
       */
      BnodeStringTemplateFunctionSymbol getFreshBnodeStringTemplateFunctionSymbol(int arity);
  
      /**
       * Temporary conversion function for the lexical part of an RDF term.
       *
       * ONLY for pre-processed mapping assertions
       * (TEMPORARY usage, to be replaced later on in the process by a fully defined cast function)
       *
       */
      DBTypeConversionFunctionSymbol getTemporaryConversionToDBStringFunctionSymbol();
  
      DBTypeConversionFunctionSymbol getDBCastFunctionSymbol(DBTermType targetType);
      DBTypeConversionFunctionSymbol getDBCastFunctionSymbol(DBTermType inputType, DBTermType targetType);
  
      /**
       * The output type is a DB string.
       *
       * This function symbol MAY also perform some normalization.
       *
       */
      DBTypeConversionFunctionSymbol getConversion2RDFLexicalFunctionSymbol(DBTermType inputType, RDFTermType rdfTermType);
  
      /**
       * From a possibly "normalized" DB string to another DB type
       */
      DBTypeConversionFunctionSymbol getConversionFromRDFLexical2DBFunctionSymbol(DBTermType targetDBType, RDFTermType rdfType);
  
      /**
       * From a possibly "normalized" DB string to another DB type
       */
      DBTypeConversionFunctionSymbol getConversionFromRDFLexical2DBFunctionSymbol(DBTermType targetDBType);
  
  
      /**
       * A regular function symbol if a function symbol that can be identified by its name in the DB dialect.
       * It can therefore be used in the input mapping document.
       *
       * Not for special DB function symbols such as casts.
       *
       */
      DBFunctionSymbol getRegularDBFunctionSymbol(String nameInDialect, int arity);
  
      /**
       * A regular function symbol if a function symbol that can be identified by its name in the DB dialect.
       * It can therefore be used in the input mapping document.
       *
       * Not for special DB function symbols such as casts.
       *
       */
      DBBooleanFunctionSymbol getRegularDBBooleanFunctionSymbol(String nameInDialect, int arity);
  
      /**
       * IF THEN, ELSE IF ..., ELSE
       *
       * Arity must be odd and {@code >= 3 }
       *
       * doOrderingMatter: if false, the when pairs can be re-ordered
       */
      DBFunctionSymbol getDBCase(int arity, boolean doOrderingMatter);
  
      DBBooleanFunctionSymbol getDBBooleanCase(int arity, boolean doOrderingMatter);
  
      DBIfElseNullFunctionSymbol getDBIfElseNull();
  
      DBBooleanFunctionSymbol getDBBooleanIfElseNull();
  
      DBFunctionSymbol getDBIfThenElse();
  
      DBFunctionSymbol getDBNullIf();
  
      DBFunctionSymbol getDBUpper();
  
      DBFunctionSymbol getDBLower();
  
      DBFunctionSymbol getDBReplace();
  
      DBFunctionSymbol getDBRegexpReplace3();
  
      DBFunctionSymbol getDBRegexpReplace4();
  
      DBFunctionSymbol getDBSubString2();
  
      DBFunctionSymbol getDBSubString3();
  
      DBFunctionSymbol getDBRight();
  
      DBFunctionSymbol getDBCharLength();
  
      DBFunctionSymbol getR2RMLIRISafeEncode();
  
      DBFunctionSymbol getDBEncodeForURI();
  
      /**
       * arity must be {@code >= 2 }
       *
       * Returns a function symbol that does NOT tolerate NULLs
       *
       */
      DBConcatFunctionSymbol getNullRejectingDBConcat(int arity);
  
      /**
       * arity must be {@code >= 2}
       *
       * No guarantee on the semantics (dialect-specific!).
       * Please consider the use of getNullRejectingDBConcat(...)
       *
       * Intended to be used by the mapping parser
       *
       */
      DBConcatFunctionSymbol getDBConcatOperator(int arity);
  
      /**
       * arity must be {@code >= 2 }
       */
      DBAndFunctionSymbol getDBAnd(int arity);
  
      /**
       * arity must be {@code >= 2 }
       */
      DBOrFunctionSymbol getDBOr(int arity);
  
      DBNotFunctionSymbol getDBNot();
  
      DBIsNullOrNotFunctionSymbol getDBIsNull();
      DBIsNullOrNotFunctionSymbol getDBIsNotNull();
  
      /**
       * Min arity is 1
       */
      DBFunctionSymbol getDBCoalesce(int arity);
  
      /**
       * Min arity is 1
       */
      DBBooleanFunctionSymbol getDBBooleanCoalesce(int arity);
  
      FalseOrNullFunctionSymbol getFalseOrNullFunctionSymbol(int arity);
  
      TrueOrNullFunctionSymbol getTrueOrNullFunctionSymbol(int arity);
  
      DBStrictEqFunctionSymbol getDBStrictEquality(int arity);
  
      DBBooleanFunctionSymbol getDBStrictNEquality(int arity);
  
      DBBooleanFunctionSymbol getDBNonStrictNumericEquality();
      DBBooleanFunctionSymbol getDBNonStrictStringEquality();
      DBBooleanFunctionSymbol getDBNonStrictDatetimeEquality();
      DBBooleanFunctionSymbol getDBNonStrictDateEquality();
      DBBooleanFunctionSymbol getDBNonStrictDefaultEquality();
  
      DBBooleanFunctionSymbol getDBNumericInequality(InequalityLabel inequalityLabel);
      DBBooleanFunctionSymbol getDBBooleanInequality(InequalityLabel inequalityLabel);
      DBBooleanFunctionSymbol getDBStringInequality(InequalityLabel inequalityLabel);
      DBBooleanFunctionSymbol getDBDatetimeInequality(InequalityLabel inequalityLabel);
      DBBooleanFunctionSymbol getDBDateInequality(InequalityLabel inequalityLabel);
      DBBooleanFunctionSymbol getDBDefaultInequality(InequalityLabel inequalityLabel);
  
      DBBooleanFunctionSymbol getDBStartsWith();
  
      DBBooleanFunctionSymbol getDBEndsWith();
  
      DBBooleanFunctionSymbol getDBIsStringEmpty();
  
      DBIsTrueFunctionSymbol getIsTrue();
  
      /**
       * Arity 2, first argument is the string in which to search, second argument is subString
       */
      DBBooleanFunctionSymbol getDBContains();
  
      NonDeterministicDBFunctionSymbol getDBRand(UUID uuid);
      NonDeterministicDBFunctionSymbol getDBUUID(UUID uuid);
  
      DBBooleanFunctionSymbol getDBRegexpMatches2();
      DBBooleanFunctionSymbol getDBRegexpMatches3();
  
      DBBooleanFunctionSymbol getDBLike();
      DBBooleanFunctionSymbol getDBSimilarTo();
  
      DBFunctionSymbol getDBStrBefore();
      DBFunctionSymbol getDBStrAfter();
  
      DBFunctionSymbol getDBMd5();
      DBFunctionSymbol getDBSha1();
      DBFunctionSymbol getDBSha256();
      DBFunctionSymbol getDBSha384();
      DBFunctionSymbol getDBSha512();
  
      DBMathBinaryOperator getDBMathBinaryOperator(String dbMathOperatorName, DBTermType dbNumericType);
  
      /**
       * Please use getDBMathBinaryOperator(...) if you know the type
       */
      DBMathBinaryOperator getUntypedDBMathBinaryOperator(String dbMathOperatorName);
  
      Optional<DBFunctionSymbol> getAbs(DBTermType dbTermType);
      Optional<DBFunctionSymbol> getCeil(DBTermType dbTermType);
      Optional<DBFunctionSymbol> getFloor(DBTermType dbTermType);
      Optional<DBFunctionSymbol> getRound(DBTermType dbTermType);
  
      DBFunctionSymbol getDBYearFromDatetime();
      DBFunctionSymbol getDBYearFromDate();
      DBFunctionSymbol getDBMonthFromDatetime();
      DBFunctionSymbol getDBMonthFromDate();
      DBFunctionSymbol getDBDayFromDatetime();
      DBFunctionSymbol getDBDayFromDate();
      DBFunctionSymbol getDBHours();
      DBFunctionSymbol getDBMinutes();
      DBFunctionSymbol getDBSeconds();
      DBFunctionSymbol getDBTz();
      DBFunctionSymbol getDBNow();
  
      DBFunctionSymbol getExtractFunctionSymbol(String component);
      DBFunctionSymbol getCurrentDateTimeSymbol(String type);
  
      /**
       * The functional term using it may be simplifiable to a regular NULL or not, depending on the DB system.
       *
       * Useful for PostgreSQL which has limited type inference capabilities when it comes to NULL and UNION (ALL).
       *
       */
      DBFunctionSymbol getTypedNullFunctionSymbol(DBTermType termType);
  
      /**
       * Returns a DB string that unique to the row
       */
      DBFunctionSymbol getDBRowUniqueStr();
  
      /**
       * Returns a different number for each row (e.g. ROWNUM of Oracle)
       */
      DBFunctionSymbol getDBRowNumber();
  
      /**
       * Considers OrderBy when handling ROW_NUM() for pre 2012 versions of SQL Server
       */
      DBFunctionSymbol getDBRowNumberWithOrderBy();
  
      DBFunctionSymbol getDBIriStringResolver(IRI baseIRI);
  
  
      //-------------
      // Aggregation
      //-------------
  
      /**
       * {@code arity <= 1 }
       */
      DBFunctionSymbol getDBCount(int arity, boolean isDistinct);
  
      /**
       * Ignores nulls.
       * Returns NULL if the bag/set does not contain any non-null value.
       */
      DBFunctionSymbol getNullIgnoringDBSum(DBTermType dbType, boolean isDistinct);
  
      /**
       * Semantics not guaranteed (may depend on the dialect)!
       */
      DBFunctionSymbol getDBSum(DBTermType dbType, boolean isDistinct);
  
      /**
       * Ignores nulls.
       * Returns NULL if the bag/set does not contain any non-null value.
       */
      DBFunctionSymbol getNullIgnoringDBAvg(DBTermType dbType, boolean isDistinct);
  
      DBFunctionSymbol getDBMin(DBTermType dbType);
      DBFunctionSymbol getDBMax(DBTermType dbType);
  
      DBFunctionSymbol getNullIgnoringDBGroupConcat(boolean isDistinct);
  
      /**
       * The first sub-term encodes the index of the term to return.
       * Such values correspond to the following sub-terms
       *
       * For instance DB_IDX(1, "roger", "francis", "ernest") returns "francis"
       *
       * TODO: find a better name
       *
       */
      DBFunctionSymbol getDBIntIndex(int nbValues);
  
      // Topological functions
      DBBooleanFunctionSymbol getDBSTWithin();
      DBBooleanFunctionSymbol getDBSTEquals();
      DBBooleanFunctionSymbol getDBSTIntersects();
      DBBooleanFunctionSymbol getDBSTOverlaps();
      DBBooleanFunctionSymbol getDBSTContains();
      DBBooleanFunctionSymbol getDBSTCrosses();
      DBBooleanFunctionSymbol getDBSTDisjoint();
      DBBooleanFunctionSymbol getDBSTTouches();
      DBBooleanFunctionSymbol getDBSTCoveredBy();
      DBBooleanFunctionSymbol getDBSTCovers();
      DBBooleanFunctionSymbol getDBSTContainsProperly();
  
      // Non-topological and form functions
      DBFunctionSymbol getDBSTDistance();
      DBFunctionSymbol getDBSTDistanceSphere();
      DBFunctionSymbol getDBSTDistanceSpheroid();
      DBFunctionSymbol getDBSTTransform();
      DBFunctionSymbol getDBSTGeomFromText();
      DBFunctionSymbol getDBSTMakePoint();
      DBFunctionSymbol getDBSTSetSRID();
      FunctionSymbol getDBAsText();
      FunctionSymbol getDBSTFlipCoordinates();
      FunctionSymbol getDBBuffer();
      FunctionSymbol getDBIntersection();
      FunctionSymbol getDBBoundary();
      FunctionSymbol getDBSymDifference();
      FunctionSymbol getDBUnion();
      FunctionSymbol getDBEnvelope();
      FunctionSymbol getDBConvexHull();
      FunctionSymbol getDBDifference();
      DBBooleanFunctionSymbol getDBRelate();
      FunctionSymbol getDBRelateMatrix();
      FunctionSymbol getDBGetSRID();
  
      // Time extension - duration arithmetic
      DBFunctionSymbol getDBWeeksBetweenFromDateTime();
      DBFunctionSymbol getDBWeeksBetweenFromDate();
      DBFunctionSymbol getDBDaysBetweenFromDateTime();
      DBFunctionSymbol getDBDaysBetweenFromDate();
      DBFunctionSymbol getDBHoursBetweenFromDateTime();
      DBFunctionSymbol getDBMinutesBetweenFromDateTime();
      DBFunctionSymbol getDBSecondsBetweenFromDateTime();
      DBFunctionSymbol getDBMillisBetweenFromDateTime();
  
      //JSON
      DBFunctionSymbol getDBJsonElt(ImmutableList<String> path);
      DBFunctionSymbol getDBJsonEltAsText(ImmutableList<String> path);
      DBBooleanFunctionSymbol getDBJsonIsNumber(DBTermType dbType);
      DBBooleanFunctionSymbol getDBJsonIsBoolean(DBTermType dbType);
      DBBooleanFunctionSymbol getDBJsonIsScalar(DBTermType dbType);
      DBBooleanFunctionSymbol getDBIsArray(DBTermType dbType);
  
      IRISafenessDeclarationFunctionSymbol getIRISafenessDeclaration();
  
  }
  