com.landawn.abacus.util.SQLMapper Maven / Gradle / Ivy
/*
* Copyright (C) 2015 HaiYang Li
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.landawn.abacus.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;
import com.landawn.abacus.exception.ParseException;
import com.landawn.abacus.exception.UncheckedIOException;
/**
* the sql scripts are configured in xml file and mapped to short ids referenced in program. for example:
* {@code }
* {@code select * from account where id=1 }
* {@code update account set name=? where id=? }
* {@code }
*
* @author Haiyang Li
* @since 0.8
*/
public final class SQLMapper {
public static final String SQL_MAPPER = "sqlMapper";
public static final String SQL = "sql";
public static final String ID = "id";
public static final String BATCH_SIZE = "batchSize";
public static final String FETCH_SIZE = "fetchSize";
public static final String RESULT_SET_TYPE = "resultSetType";
public static final ImmutableMap RESULT_SET_TYPE_MAP = ImmutableMap.of("FORWARD_ONLY", ResultSet.TYPE_FORWARD_ONLY, "SCROLL_INSENSITIVE",
ResultSet.TYPE_SCROLL_INSENSITIVE, "SCROLL_SENSITIVE", ResultSet.TYPE_SCROLL_SENSITIVE);
public static final String TIMEOUT = "timeout";
public static final int MAX_ID_LENGTH = 64;
private final Map sqlMap = new LinkedHashMap<>();
private final Map> attrsMap = new HashMap<>();
public SQLMapper() {
// empty constructor
}
/**
*
* @param filePath it could be multiple file paths separated by ',' or ';'
* @return
*/
public static SQLMapper fromFile(String filePath) {
String[] filePaths = Splitter.with(WD.COMMA).trimResults().splitToArray(filePath);
if (filePaths.length == 1) {
filePaths = Splitter.with(WD.SEMICOLON).trimResults().splitToArray(filePath);
}
final SQLMapper sqlMapper = new SQLMapper();
for (String subFilePath : filePaths) {
final File file = Configuration.formatPath(Configuration.findFile(subFilePath));
try (InputStream is = new FileInputStream(file)) {
Document doc = XMLUtil.createDOMParser(true, true).parse(is);
NodeList sqlMapperEle = doc.getElementsByTagName(SQLMapper.SQL_MAPPER);
if (0 == sqlMapperEle.getLength()) {
throw new RuntimeException("There is no 'sqlMapper' element. ");
}
List sqlElementList = XMLUtil.getElementsByTagName((Element) sqlMapperEle.item(0), SQL);
for (Element sqlElement : sqlElementList) {
Map attrMap = XMLUtil.readAttributes(sqlElement);
sqlMapper.add(attrMap.remove(ID), Configuration.getTextContent(sqlElement), attrMap);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (SAXException e) {
throw new ParseException(e);
}
}
return sqlMapper;
}
public Set keySet() {
return sqlMap.keySet();
}
/**
*
* @param id
* @return
*/
public ParsedSql get(String id) {
if (N.isNullOrEmpty(id) || id.length() > MAX_ID_LENGTH) {
return null;
}
return sqlMap.get(id);
}
/**
* Gets the attrs.
*
* @param id
* @return
*/
public ImmutableMap getAttrs(String id) {
if (N.isNullOrEmpty(id) || id.length() > MAX_ID_LENGTH) {
return null;
}
return attrsMap.get(id);
}
/**
*
* @param id
* @param sql
* @return
*/
public ParsedSql add(String id, ParsedSql sql) {
checkId(id);
return sqlMap.put(id, sql);
}
/**
*
* @param id
* @param sql
* @param attrs
*/
public void add(String id, String sql, Map attrs) {
checkId(id);
sqlMap.put(id, ParsedSql.parse(sql));
attrsMap.put(id, ImmutableMap.copyOf(attrs));
}
/**
*
* @param id
*/
private void checkId(String id) {
N.checkArgNotNullOrEmpty(id, "id");
if (id.length() > MAX_ID_LENGTH) {
throw new IllegalArgumentException("Id: " + id + " is too long. The maximum length for id is: " + MAX_ID_LENGTH);
}
if (sqlMap.containsKey(id)) {
throw new IllegalArgumentException(id + " already exists with sql: " + sqlMap.get(id));
}
}
/**
*
* @param id
*/
public void remove(String id) {
if (N.isNullOrEmpty(id) || id.length() > MAX_ID_LENGTH) {
return;
}
sqlMap.remove(id);
}
public SQLMapper copy() {
final SQLMapper copy = new SQLMapper();
copy.sqlMap.putAll(this.sqlMap);
copy.attrsMap.putAll(this.attrsMap);
return copy;
}
/**
*
* @param file
*/
public void saveTo(File file) {
try (OutputStream os = new FileOutputStream(file);) {
Document doc = XMLUtil.createDOMParser(true, true).newDocument();
Element sqlMapperNode = doc.createElement(SQLMapper.SQL_MAPPER);
for (Map.Entry sqlEntry : sqlMap.entrySet()) {
Element sqlNode = doc.createElement(SQL);
sqlNode.setAttribute(ID, sqlEntry.getKey());
if (!N.isNullOrEmpty(attrsMap.get(sqlEntry.getKey()))) {
Map attrs = attrsMap.get(sqlEntry.getKey());
for (Map.Entry entry : attrs.entrySet()) {
sqlNode.setAttribute(entry.getKey(), entry.getValue());
}
}
Text sqlText = doc.createTextNode(sqlEntry.getValue().sql());
sqlNode.appendChild(sqlText);
sqlMapperNode.appendChild(sqlNode);
}
doc.appendChild(sqlMapperNode);
if (!file.exists()) {
file.createNewFile(); //NOSONAR
}
XMLUtil.transform(doc, os);
os.flush();
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public boolean isEmpty() {
return sqlMap.isEmpty();
}
@Override
public int hashCode() {
return sqlMap.hashCode();
}
/**
*
* @param obj
* @return
*/
@Override
public boolean equals(Object obj) {
return this == obj || (obj instanceof SQLMapper && N.equals(((SQLMapper) obj).sqlMap, sqlMap));
}
@Override
public String toString() {
return sqlMap.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy