001package gudusoft.gsqlparser.sqlenv.catalog; 002 003import gudusoft.gsqlparser.EDbVendor; 004import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType; 005import gudusoft.gsqlparser.sqlenv.IdentifierProfile; 006import gudusoft.gsqlparser.sqlenv.IdentifierService; 007import gudusoft.gsqlparser.sqlenv.TSQLCatalog; 008import gudusoft.gsqlparser.sqlenv.TSQLEnv; 009import gudusoft.gsqlparser.sqlenv.TSQLSchemaObject; 010import gudusoft.gsqlparser.sqlenv.calcite.CatalogStore; 011 012import java.util.ArrayList; 013import java.util.List; 014import java.util.HashMap; 015import java.util.Map; 016 017/** 018 * CatalogStore Provider(新实现) 019 * 020 * <p>此实现基于 CatalogStore,使用 IdentifierService 进行标识符处理。 021 * 022 * @since 3.2.0 (Phase 1) 023 */ 024public class CatalogStoreProvider implements ICatalogProvider { 025 026 private final EDbVendor vendor; 027 private final CatalogStore catalogStore; 028 private final IdentifierService identifierService; 029 private String defaultCatalogName; 030 031 // Cache for TSQLCatalog objects (for compatibility with TSQLEnv API) 032 private final Map<String, TSQLCatalog> catalogCache = new HashMap<>(); 033 034 /** 035 * Creates a CatalogStoreProvider with default flags 036 * 037 * @param vendor database vendor 038 */ 039 public CatalogStoreProvider(EDbVendor vendor) { 040 this(vendor, IdentifierProfile.VendorFlags.defaults()); 041 } 042 043 /** 044 * Creates a CatalogStoreProvider with custom vendor flags 045 * 046 * @param vendor database vendor 047 * @param flags vendor-specific flags 048 */ 049 public CatalogStoreProvider(EDbVendor vendor, IdentifierProfile.VendorFlags flags) { 050 this.vendor = vendor; 051 052 // Create IdentifierProfile and IdentifierService 053 IdentifierProfile profile = IdentifierProfile.forVendor(vendor, flags); 054 gudusoft.gsqlparser.sqlenv.CollatorProvider collatorProvider = null; 055 if (vendor == EDbVendor.dbvmssql || vendor == EDbVendor.dbvazuresql) { 056 collatorProvider = new gudusoft.gsqlparser.sqlenv.CollatorProvider(); 057 } 058 this.identifierService = new IdentifierService(profile, collatorProvider); 059 060 // Create CatalogStore with IdentifierService for proper normalization 061 this.catalogStore = new CatalogStore(vendor, this.identifierService); 062 } 063 064 /** 065 * Creates a CatalogStoreProvider wrapping existing CatalogStore 066 * 067 * @param catalogStore existing catalog store 068 * @param identifierService identifier service 069 */ 070 public CatalogStoreProvider(CatalogStore catalogStore, IdentifierService identifierService) { 071 this.vendor = catalogStore.getVendor(); 072 this.catalogStore = catalogStore; 073 this.identifierService = identifierService; 074 } 075 076 @Override 077 public TSQLCatalog getCatalog(String catalogName) { 078 if (catalogName == null || catalogName.isEmpty()) { 079 return null; 080 } 081 082 // Normalize catalog name 083 String normalizedName = identifierService.normalize(catalogName, ESQLDataObjectType.dotCatalog); 084 085 // Return cached catalog if exists 086 return catalogCache.get(normalizedName); 087 } 088 089 @Override 090 public TSQLCatalog createCatalog(String catalogName) { 091 if (catalogName == null || catalogName.isEmpty()) { 092 throw new IllegalArgumentException("catalogName cannot be null or empty"); 093 } 094 095 // Normalize catalog name 096 String normalizedName = identifierService.normalize(catalogName, ESQLDataObjectType.dotCatalog); 097 098 // Return existing if already cached 099 TSQLCatalog existing = catalogCache.get(normalizedName); 100 if (existing != null) { 101 return existing; 102 } 103 104 // Note: We cannot create TSQLCatalog here because it requires TSQLEnv 105 // This is a limitation of the current architecture 106 // For now, return null and let the caller handle it 107 // In Phase 2-3, we'll refactor TSQLCatalog to not require TSQLEnv 108 109 return null; 110 } 111 112 @Override 113 public List<TSQLCatalog> getAllCatalogs() { 114 return new ArrayList<>(catalogCache.values()); 115 } 116 117 @Override 118 public String getDefaultCatalogName() { 119 return defaultCatalogName; 120 } 121 122 @Override 123 public void setDefaultCatalogName(String name) { 124 this.defaultCatalogName = name; 125 } 126 127 @Override 128 public TSQLSchemaObject findObject(String catalog, String schema, 129 String objectName, ESQLDataObjectType type) { 130 // Delegate directly to CatalogStore (it handles normalization internally) 131 return catalogStore.get(catalog, schema, objectName, type); 132 } 133 134 @Override 135 public void addObject(TSQLSchemaObject object) { 136 if (object == null) { 137 return; 138 } 139 140 // Add to CatalogStore 141 catalogStore.put(object); 142 143 // Update catalog cache if needed 144 if (object.getSchema() != null && object.getSchema().getCatalog() != null) { 145 TSQLCatalog catalog = object.getSchema().getCatalog(); 146 String normalizedName = identifierService.normalize( 147 catalog.getName(), 148 ESQLDataObjectType.dotCatalog 149 ); 150 catalogCache.putIfAbsent(normalizedName, catalog); 151 } 152 } 153 154 @Override 155 public boolean removeObject(TSQLSchemaObject object) { 156 if (object == null) { 157 return false; 158 } 159 160 return catalogStore.remove(object); 161 } 162 163 @Override 164 public void clear() { 165 catalogStore.clear(); 166 catalogCache.clear(); 167 } 168 169 @Override 170 public int size() { 171 return catalogStore.size(); 172 } 173 174 /** 175 * Get the underlying CatalogStore 176 * 177 * @return catalog store 178 */ 179 public CatalogStore getCatalogStore() { 180 return catalogStore; 181 } 182 183 /** 184 * Get the IdentifierService 185 * 186 * @return identifier service 187 */ 188 public IdentifierService getIdentifierService() { 189 return identifierService; 190 } 191 192 /** 193 * Register a catalog in the cache (used by TSQLEnv during migration) 194 * 195 * @param catalog the catalog to register 196 */ 197 public void registerCatalog(TSQLCatalog catalog) { 198 if (catalog == null) { 199 return; 200 } 201 202 String normalizedName = identifierService.normalize( 203 catalog.getName(), 204 ESQLDataObjectType.dotCatalog 205 ); 206 catalogCache.put(normalizedName, catalog); 207 } 208}