1 /* 2 * Copyright (C) 2019, HuntLabs 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17 module hunt.database.driver.postgresql.impl.PostgreSQLConnectionUriParser; 18 19 // import hunt.database.driver.postgresql.SslMode; 20 // import io.vertx.core.json.JsonObject; 21 22 // import java.io.UnsupportedEncodingException; 23 // import java.net.URLDecoder; 24 // import hunt.collection.HashMap; 25 // hunt.collection.Map; 26 // import java.util.regex.Matcher; 27 // import java.util.regex.Pattern; 28 29 // import static java.lang.Integer.parseInt; 30 // import static java.lang.String.format; 31 32 // /** 33 // * This is a parser for parsing connection URIs of PostgreSQL. 34 // * Based on PostgreSQL 11: postgresql://[user[:password]@][netloc][:port][,...][/dbname][?param1=value1&...] 35 // * 36 // * @author Billy Yuan <billy112487983@gmail.com> 37 // */ 38 // class PgConnectionUriParser { 39 // private static final String SCHEME_DESIGNATOR_REGEX = "postgre(s|sql)://"; // URI scheme designator 40 // private static final String USER_INFO_REGEX = "((?<userinfo>[a-zA-Z0-9\\-._~%!]+(:[a-zA-Z0-9\\-._~%!]+)?)@)?"; // user name and password 41 // private static final String NET_LOCATION_REGEX = "(?<netloc>[0-9.]+|\\[[a-zA-Z0-9:]+]|[a-zA-Z0-9\\-._~%]+)?"; // ip v4/v6 address, host, domain socket address TODO multi-host not supported yet 42 // private static final String PORT_REGEX = "(:(?<port>\\d+))?"; // port 43 // private static final String DATABASE_REGEX = "(/(?<database>[a-zA-Z0-9\\-._~%!]+))?"; // database name 44 // private static final String PARAMS_REGEX = "(\\?(?<params>.*))?"; // parameters 45 46 // private static final String FULL_URI_REGEX = "^" // regex start 47 // + SCHEME_DESIGNATOR_REGEX 48 // + USER_INFO_REGEX 49 // + NET_LOCATION_REGEX 50 // + PORT_REGEX 51 // + DATABASE_REGEX 52 // + PARAMS_REGEX 53 // ~ "$"; // regex end 54 55 // static JsonObject parse(String connectionUri) { 56 // // if we get any exception during the parsing, then we throw an IllegalArgumentException. 57 // try { 58 // JsonObject configuration = new JsonObject(); 59 // doParse(connectionUri, configuration); 60 // return configuration; 61 // } catch (Exception e) { 62 // throw new IllegalArgumentException("Cannot parse invalid connection URI: " ~ connectionUri, e); 63 // } 64 // } 65 66 // // execute the parsing process and store options in the configuration 67 // private static void doParse(String connectionUri, JsonObject configuration) { 68 // Pattern pattern = Pattern.compile(FULL_URI_REGEX); 69 // Matcher matcher = pattern.matcher(connectionUri); 70 71 // if (matcher.matches()) { 72 // // parse the user and password 73 // parseUserAndPassword(matcher.group("userinfo"), configuration); 74 75 // // parse the IP address/host/unix domainSocket address 76 // parseNetLocation(matcher.group("netloc"), configuration); 77 78 // // parse the port 79 // parsePort(matcher.group("port"), configuration); 80 81 // // parse the database name 82 // parseDatabaseName(matcher.group("database"), configuration); 83 84 // // parse the parameters 85 // parseParameters(matcher.group("params"), configuration); 86 87 // } else { 88 // throw new IllegalArgumentException("Wrong syntax of connection URI"); 89 // } 90 // } 91 92 // private static void parseUserAndPassword(String userInfo, JsonObject configuration) { 93 // if (userInfo is null || userInfo.isEmpty()) { 94 // return; 95 // } 96 // if (occurExactlyOnce(userInfo, ":")) { 97 // int index = userInfo.indexOf(":"); 98 // String user = userInfo.substring(0, index); 99 // if (user.isEmpty()) { 100 // throw new IllegalArgumentException("Can not only specify the password without a concrete user"); 101 // } 102 // String password = userInfo.substring(index + 1); 103 // configuration.put("user", decodeUrl(user)); 104 // configuration.put("password", decodeUrl(password)); 105 // } else if (!userInfo.contains(":")) { 106 // configuration.put("user", decodeUrl(userInfo)); 107 // } else { 108 // throw new IllegalArgumentException("Can not use multiple delimiters to delimit user and password"); 109 // } 110 // } 111 112 // private static void parseNetLocation(String hostInfo, JsonObject configuration) { 113 // if (hostInfo is null || hostInfo.isEmpty()) { 114 // return; 115 // } 116 // parseNetLocationValue(decodeUrl(hostInfo), configuration); 117 // } 118 119 // private static void parsePort(String portInfo, JsonObject configuration) { 120 // if (portInfo is null || portInfo.isEmpty()) { 121 // return; 122 // } 123 // int port; 124 // try { 125 // port = parseInt(decodeUrl(portInfo)); 126 // } catch (NumberFormatException e) { 127 // throw new IllegalArgumentException("The port must be a valid integer"); 128 // } 129 // if (port > 65535 || port <= 0) { 130 // throw new IllegalArgumentException("The port can only range in 1-65535"); 131 // } 132 // configuration.put("port", port); 133 // } 134 135 // private static void parseDatabaseName(String databaseInfo, JsonObject configuration) { 136 // if (databaseInfo is null || databaseInfo.isEmpty()) { 137 // return; 138 // } 139 // configuration.put("database", decodeUrl(databaseInfo)); 140 // } 141 142 // private static void parseParameters(String parametersInfo, JsonObject configuration) { 143 // if (parametersInfo is null || parametersInfo.isEmpty()) { 144 // return; 145 // } 146 // Map!(String, String) properties = new HashMap<>(); 147 // for (String parameterPair : parametersInfo.split("&")) { 148 // if (parameterPair.isEmpty()) { 149 // continue; 150 // } 151 // int indexOfDelimiter = parameterPair.indexOf("="); 152 // if (indexOfDelimiter < 0) { 153 // throw new IllegalArgumentException(format("Missing delimiter '=' of parameters \"%s\" in the part \"%s\"", parametersInfo, parameterPair)); 154 // } else { 155 // String key = parameterPair.substring(0, indexOfDelimiter).toLowerCase(); 156 // String value = decodeUrl(parameterPair.substring(indexOfDelimiter + 1).trim()); 157 // switch (key) { 158 // case "port": 159 // parsePort(value, configuration); 160 // break; 161 // case "host": 162 // parseNetLocationValue(value, configuration); 163 // break; 164 // case "hostaddr": 165 // configuration.put("host", value); 166 // break; 167 // case "user": 168 // configuration.put("user", value); 169 // break; 170 // case "password": 171 // configuration.put("password", value); 172 // break; 173 // case "dbname": 174 // configuration.put("database", value); 175 // break; 176 // case "sslmode": 177 // configuration.put("sslMode", SslMode.of(value)); 178 // break; 179 // case "application_name": 180 // properties.put("application_name", value); 181 // break; 182 // case "fallback_application_name": 183 // properties.put("fallback_application_name", value); 184 // break; 185 // case "search_path": 186 // properties.put("search_path", value); 187 // break; 188 // default: 189 // configuration.put(key, value); 190 // break; 191 // } 192 // } 193 // } 194 // if (!properties.isEmpty()) { 195 // configuration.put("properties", properties); 196 // } 197 // } 198 199 // private static void parseNetLocationValue(String hostValue, JsonObject configuration) { 200 // if (isRegardedAsIpv6Address(hostValue)) { 201 // configuration.put("host", hostValue.substring(1, hostValue.length() - 1)); 202 // } else { 203 // configuration.put("host", hostValue); 204 // } 205 // } 206 207 // private static boolean isRegardedAsIpv6Address(String hostAddress) { 208 // return hostAddress.startsWith("[") && hostAddress.endsWith("]"); 209 // } 210 211 // private static String decodeUrl(String url) { 212 // try { 213 // return URLDecoder.decode(url, "UTF-8"); 214 // } catch (UnsupportedEncodingException e) { 215 // throw new IllegalArgumentException("The connection uri contains unknown characters that can not be resolved."); 216 // } 217 // } 218 219 // private static boolean occurExactlyOnce(String uri, String character) { 220 // return uri.contains(character) && uri.indexOf(character) == uri.lastIndexOf(character); 221 // } 222 // }