001package gudusoft.gsqlparser.sqlenv;
002
003import gudusoft.gsqlparser.EDbVendor;
004
005import static gudusoft.gsqlparser.sqlenv.ESQLDataObjectType.*;
006
007/**
008 * base class of all the database object such as catalog, schema, table, column and etc
009 */
010public abstract class TSQLObject {
011    protected String name = null;
012    protected String nameKeepCase = null;
013
014    protected TSQLEnv sqlEnv;
015
016    /**
017     * SQL environment where this database object belonged to.
018     *
019     * @return SQL environment
020     */
021    public TSQLEnv getSqlEnv() {
022        return sqlEnv;
023    }
024
025
026    /**
027     * create a new database object and add to the SQL environment.
028     *
029     * @param sqlEnv SQL environment
030     * @param objectName object name
031     */
032    public TSQLObject(TSQLEnv sqlEnv, String objectName, ESQLDataObjectType dataObjectType){
033        this.sqlEnv = sqlEnv;
034        this.nameKeepCase = objectName;
035        // The type must be set before the name is normalized: normalizeIdentifier reads it, and
036        // with the field still at dotUnknown a MySQL-family column, function, procedure or
037        // trigger was folded by the table rule (Amount -> amount) instead of its own.
038        if (dataObjectType != null) {
039            this.dataObjectType = dataObjectType;
040        }
041        this.name = normalizeIdentifier(objectName);
042    }
043
044    /**
045     * name of this database object. With the case unchanged.
046     * @return database object name
047     */
048    public String getNameKeepCase() {
049        return nameKeepCase;
050    }
051
052    /**
053     * name of this database object. case of the name was normalized according to the database vendor's implementation.
054     * If the name was picked up from a SQL script, it's case maybe changed and not the same as it appeared in the SQL script.
055     *
056     * @return name
057     */
058    public String getName(){
059        return name;
060    }
061
062    public void setDataObjectType(ESQLDataObjectType dataObjectType) {
063        this.dataObjectType = dataObjectType;
064    }
065
066    protected ESQLDataObjectType dataObjectType = dotUnknown;
067
068    /**
069     * Type of this database object
070     *
071     * @return database object type
072     */
073    public ESQLDataObjectType getDataObjectType(){
074        return dataObjectType;
075    }
076
077    /**
078     * qualified name for database object such as: databaseName.schemaName.tableName
079     * @return qualified name
080     */
081    public String getQualifiedName(){
082        return "";
083    }
084
085
086    /**
087     * whether is this a delimited identifier.
088     *
089     * @param identifier name of a database object
090     * @return true if it's a delimited/quoted identifer.
091     */
092    public boolean isDelimitedIdentifier(String identifier){
093        return  isDelimitedIdentifier(this.sqlEnv,identifier);
094    }
095
096    /**
097     * Change the case of the name of database object.
098     *
099     * @param identifier database object name
100     * @return normalized database object name
101     */
102    public String normalizeIdentifier(String identifier){
103        return this.sqlEnv.normalizeIdentifier(this.dataObjectType,identifier);
104    }
105
106    /**
107     * compare the name of this object to objectname with carefully handle of the case [in]sensitive.
108     *
109     * @param objectName object name need to be compared
110     * @return a negative integer, zero, or a positive integer as the
111     *         specified String is greater than, equal to, or less than this object name
112     *
113     */
114    public int compareTo(String objectName){
115        return compareTo(this.sqlEnv,this.getDataObjectType(),this,objectName);
116    }
117
118    /**
119     * check whether a database object name is a delimited identifier or not based on the database.
120     *
121     * @param sqlEnv SQL environment
122     * @param identifier database object name
123     * @return true if it's delimited/quoted identifier
124     */
125    public static boolean isDelimitedIdentifier(TSQLEnv sqlEnv, String identifier){
126        return TSQLEnv.isDelimitedIdentifier(sqlEnv.getDBVendor(),identifier);
127    }
128
129
130    /**
131     * change the case of the name of the database object name, and remove the delimited char if it's a delimited identifier.
132     * <br>
133     * the case of database object name was changed when it's saved in INFORMATION_SCHEMA.
134     * In oracle, db2, it's changed to uppercase and in the PostgreSQL, it's changed to lowercase.
135     * case of the delimited identifier is unchanged when saved to the INFORMATION_SCHEMA.
136     * <br>So, the implementation is vendor dependent, this method will change the case of database object name accordingly
137     * based on the implementation of different database vendor.
138     *
139     * @param sqlEnv SQL environment
140     * @param sqlDataObjectType database object type, such as procedure, table, column
141     * @param identifier name of the database object
142     * @return normalized name of the database object
143     */
144//    public static String normalizeIdentifier(TSQLEnv sqlEnv, ESQLDataObjectType sqlDataObjectType, String identifier){
145//        //return normalizeIdentifier(sqlEnv.getDBVendor(),sqlDataObjectType,identifier);
146//        return sqlEnv.normalizeIdentifier(sqlDataObjectType,identifier);
147//    }
148
149//    public static String normalizeIdentifier(EDbVendor dbVendor, ESQLDataObjectType sqlDataObjectType, String identifier){
150//        return TSQLEnv.normalizeIdentifier(dbVendor,sqlDataObjectType,identifier);
151//    }
152
153
154    /**
155     * how to compare the name of database object is various from different databases due to the different implementation.
156     * We need to consider the database vendor, the database object type when comparing the database object name.
157     *
158     * @param sqlEnv  SQL environment
159     * @param sqlDataObjectType database object type
160     * @param targetDataObject instance of database object need to be compared
161     * @param objectName database object name
162     * @return
163     */
164    public static int compareTo(TSQLEnv sqlEnv, ESQLDataObjectType sqlDataObjectType, TSQLObject targetDataObject, String objectName){
165        return compareTo(sqlEnv.getDBVendor(),sqlDataObjectType,targetDataObject,objectName);
166    }
167
168    public static int compareTo(EDbVendor dbVendor, ESQLDataObjectType sqlDataObjectType, TSQLObject targetDataObject, String objectName){
169        return compareTo(dbVendor,sqlDataObjectType,targetDataObject.getNameKeepCase() ,objectName);
170    }
171
172    /**
173     * @deprecated since version 2.2.3.2(2021-05-10), replaced by @TSQLEnv.compareIdentifier()
174     *
175     * @param dbVendor
176     * @param sqlDataObjectType
177     * @param pTargetObjectName
178     * @param objectName
179     * @return
180     */
181    public static int compareTo(EDbVendor dbVendor, ESQLDataObjectType sqlDataObjectType, String pTargetObjectName, String objectName){
182
183        if (TSQLEnv.compareIdentifier(dbVendor,sqlDataObjectType,pTargetObjectName,objectName)) return 0;
184        else return -1;
185
186//        int ret = 0;
187//        String normalizedName = normalizeIdentifier(dbVendor, sqlDataObjectType,objectName);
188//        String targetObjectName = normalizeIdentifier(dbVendor, sqlDataObjectType,pTargetObjectName);
189//
190//        switch (dbVendor){
191//            case dbvmssql:
192//                ret =  targetObjectName.compareToIgnoreCase(normalizedName);
193//                break;
194//            case dbvmysql:
195//                if ((sqlDataObjectType == dotTable)||(sqlDataObjectType == dotTrigger)||(sqlDataObjectType == dotCatalog)){
196//                    ret = targetObjectName.compareTo(normalizedName);
197//                }else {
198//                    ret = targetObjectName.compareToIgnoreCase(normalizedName);
199//                }
200//                break;
201//            case dbvpostgresql:
202//                ret =  targetObjectName.compareTo(normalizedName);
203//                break;
204//            case dbvoracle:
205//                ret =  targetObjectName.compareTo(normalizedName);
206//                break;
207//            case dbvdb2:
208//                ret =  targetObjectName.compareTo(normalizedName);
209//                break;
210//            default:
211//                ret =  targetObjectName.compareTo(normalizedName);
212//                break;
213//        }
214//        return ret;
215    }
216
217}