com.alibaba.hologres.client.model.TableName Maven / Gradle / Ivy
/*
* Copyright (c) 2022. Alibaba Group Holding Limited
*/
package com.alibaba.hologres.client.model;
import com.alibaba.hologres.client.exception.InvalidIdentifierException;
import com.alibaba.hologres.client.utils.IdentifierUtil;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;
/**
* 表名.
*/
public class TableName implements Serializable {
public static final String DEFAULT_SCHEMA_NAME = "public";
private static final byte[] LOCK = new byte[0];
private static Map tableCache2 = new HashMap<>();
String schemaName;
String tableName;
String fullName;
private TableName(String schemaName, String tableName, String fullName) {
this.schemaName = schemaName;
this.tableName = tableName;
this.fullName = fullName;
}
public String getFullName() {
return fullName;
}
public String getSchemaName() {
return schemaName;
}
public String getTableName() {
return tableName;
}
public static TableName quoteValueOf(String schemaName, String tableName) throws InvalidIdentifierException {
return valueOf(IdentifierUtil.quoteIdentifier(schemaName, /*isCaseSensitive*/true), IdentifierUtil.quoteIdentifier(tableName, /*isCaseSensitive*/true));
}
public static TableName valueOf(String schemaName, String tableName) throws InvalidIdentifierException {
if (schemaName == null || schemaName.length() < 1) {
schemaName = DEFAULT_SCHEMA_NAME;
}
return valueOf(schemaName + "." + tableName);
}
static final Pattern IDENTIFIER_PATTERN = Pattern.compile("^[^\"\\s\\d\\-;][^\"\\s\\-;]*$");
public static String parseIdentifier(String identifier) {
List ret = parseMultiIdentifier(identifier);
if (ret == null) {
return null;
} else if (ret.size() == 1) {
return ret.get(0);
} else {
throw new InvalidIdentifierException(identifier);
}
}
public static final char QUOTE = '"';
public static final char SPLIT = '.';
public static List parseMultiIdentifier(String identifier) {
if (identifier == null) {
return null;
}
List ret = new ArrayList<>();
boolean isQuoteState = false;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < identifier.length(); ++i) {
char c = identifier.charAt(i);
if (isQuoteState) {
if (c == QUOTE) {
if (i < identifier.length() - 1) {
if (identifier.charAt(i + 1) == QUOTE) {
sb.append(QUOTE);
} else if (identifier.charAt(i + 1) == SPLIT) {
isQuoteState = false;
ret.add(sb.toString());
sb.setLength(0);
} else {
throw new InvalidIdentifierException(identifier);
}
++i;
} else {
ret.add(sb.toString());
sb.setLength(0);
}
} else {
sb.append(c);
}
} else {
char lowerC = (char) (c >= 'A' && c <= 'Z' ? c + ('a' - 'A') : c);
if (sb.length() == 0) {
if (c == QUOTE) {
isQuoteState = true;
} else if (c == SPLIT) {
throw new InvalidIdentifierException(identifier);
} else {
sb.append(lowerC);
}
} else {
if (c == QUOTE) {
throw new InvalidIdentifierException(identifier);
} else if (c == SPLIT) {
String text = sb.toString();
sb.setLength(0);
if (IDENTIFIER_PATTERN.matcher(text).find()) {
ret.add(text);
} else {
throw new InvalidIdentifierException(identifier);
}
} else {
sb.append(lowerC);
}
}
}
}
if (sb.length() > 0) {
if (isQuoteState) {
throw new InvalidIdentifierException(identifier);
}
String text = sb.toString();
sb.setLength(0);
if (IDENTIFIER_PATTERN.matcher(text).find()) {
ret.add(text);
} else {
throw new InvalidIdentifierException(identifier);
}
}
return ret;
}
public static TableName valueOf(String name) throws InvalidIdentifierException {
TableName tableName = tableCache2.get(name);
if (tableName == null) {
synchronized (LOCK) {
tableName = tableCache2.get(name);
if (tableName == null) {
List schemaAndTableName = parseMultiIdentifier(name);
String parsedSchemaName;
String parsedTableName;
if (schemaAndTableName.size() == 1) {
parsedSchemaName = DEFAULT_SCHEMA_NAME;
parsedTableName = schemaAndTableName.get(0);
} else if (schemaAndTableName.size() == 2) {
parsedSchemaName = schemaAndTableName.get(0);
parsedTableName = schemaAndTableName.get(1);
} else {
throw new InvalidIdentifierException(name);
}
StringBuilder sb = new StringBuilder();
sb.append("\"");
for (int i = 0; i < parsedSchemaName.length(); ++i) {
char c = parsedSchemaName.charAt(i);
if (c == '"') {
sb.append(c);
}
sb.append(c);
}
sb.append("\".\"");
for (int i = 0; i < parsedTableName.length(); ++i) {
char c = parsedTableName.charAt(i);
if (c == '"') {
sb.append(c);
}
sb.append(c);
}
sb.append("\"");
String parsedFullName = sb.toString();
Map temp = new HashMap<>(tableCache2);
tableName = tableCache2.get(parsedFullName);
if (tableName == null) {
tableName = new TableName(parsedSchemaName, parsedTableName, parsedFullName);
temp.put(parsedFullName, tableName);
}
temp.put(name, tableName);
tableCache2 = temp;
}
}
}
return tableName;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TableName tableName1 = (TableName) o;
return Objects.equals(schemaName, tableName1.schemaName)
&& Objects.equals(tableName, tableName1.tableName);
}
@Override
public int hashCode() {
return Objects.hash(schemaName, tableName);
}
@Override
public String toString() {
return fullName;
}
}