/** * personium.io * Copyright 2014 FUJITSU LIMITED * * 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.fujitsu.dc.core.model.impl.es.ads; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; import org.apache.commons.dbcp.DelegatingPreparedStatement; import org.apache.commons.lang.CharEncoding; import org.json.simple.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fujitsu.dc.common.utils.DcCoreUtils; import com.fujitsu.dc.core.DcCoreConfig; import com.fujitsu.dc.core.DcCoreLog; import com.fujitsu.dc.core.model.impl.es.DavNode; import com.fujitsu.dc.core.model.impl.es.doc.CellDocHandler; import com.fujitsu.dc.core.model.impl.es.doc.EntitySetDocHandler; import com.fujitsu.dc.core.model.impl.es.doc.LinkDocHandler; import com.fujitsu.dc.core.model.impl.es.doc.OEntityDocHandler; import com.fujitsu.dc.core.model.impl.es.odata.UserDataODataProducer; /** * JDBCタイプのADS ( Authentic Data Store ). */ public class JdbcAds implements Ads { private static DataSource ds; Map<String, IndexPeer> peersMap = new HashMap<String, IndexPeer>(); static Logger log = LoggerFactory.getLogger(JdbcAds.class); static final String SCHEMA_NAME_REPLACING_KEY = "##schema##"; static final boolean AUTO_COMMIT = true; static final String MANAGEMENT_DB_NAME = "pcs_management"; /** * コンストラクタ. * @throws AdsConnectionException ADS接続失敗 */ public JdbcAds() throws AdsConnectionException { try { if (ds == null) { Properties p = DcCoreConfig.getEsAdsDbcpProps(); ds = BasicDataSourceFactory.createDataSource(p); } } catch (Exception e) { log.info("Failed to create instance of Ads."); throw new AdsConnectionException(e); } } /** * Adsの接続確認を行う. * @throws AdsException 処理失敗時発生 */ public void checkConnection() throws AdsException { try { // 接続確認を行う ds.getConnection().close(); } catch (SQLException e) { // 接続失敗時は例外を出力する log.info("Failed to connect Ads."); throw new AdsException(e); } } @Override public void createEntity(String index, EntitySetDocHandler edh) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.createEntity(edh); } @Override public void updateEntity(String index, EntitySetDocHandler edh) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.updateEntity(edh); } @Override public void deleteEntity(String index, String id) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.deleteEntity(id); } /** * Entity Document一括生成に伴い、Adsの対応レコード一括生成を行う. * @param index index * @param bulkRequestList 一括生成データ * @throws AdsException 処理失敗時発生 */ @Override public void bulkEntity(String index, List<EntitySetDocHandler> bulkRequestList) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.bulkEntity(bulkRequestList); } /** * Entity Document一括更新に伴い、Adsの対応レコード一括更新を行う. * @param index index * @param bulkRequestList 一括更新データ * @throws AdsException 処理失敗時発生 */ @Override public void bulkUpdateEntity(String index, List<EntitySetDocHandler> bulkRequestList) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.bulkUpdateEntityLink(bulkRequestList); } /** * Dav Document一括更新に伴い、Adsの対応レコード一括更新を行う. * @param index index * @param bulkRequestList 一括更新データ * @throws AdsException 処理失敗時発生 */ @Override public void bulkUpdateDav(String index, List<DavNode> bulkRequestList) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.bulkUpdateDav(bulkRequestList); } @Override public void createCell(String index, EntitySetDocHandler docHandler) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.createCell(docHandler); } @Override public void updateCell(String index, EntitySetDocHandler docHandler) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.updateCell(docHandler); } @Override public void deleteCell(String index, String id) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.deleteCell(id); } @Override public void createLink(String index, LinkDocHandler ldh) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.createLink(ldh); } @Override public void updateLink(String index, LinkDocHandler ldh) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.updateLink(ldh); } @Override public void deleteLink(String index, String id) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.deleteLink(id); } @Override public void createDavNode(String index, DavNode davNode) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.createDavNode(davNode); } @Override public void updateDavNode(String index, DavNode davNode) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.updateDavNode(davNode); } @Override public void deleteDavNode(String index, String id) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.deleteDavNode(id); } @Override public long countEntity(String index) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.countEntity(); } @Override public List<JSONObject> getEntityList(String index, long offset, long size) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.getEntityList(offset, size); } @Override public long countCell(String index) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.countCell(); } @Override public List<JSONObject> getCellList(String index, long offset, long size) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.getCellList(offset, size); } @Override public long countLink(String index) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.countLink(); } @Override public List<JSONObject> searchEntityList(String index, List<String> idList) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.searchEntityList(idList); } @Override public List<JSONObject> searchCellList(String index, List<String> idList) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.searchCellList(idList); } @Override public List<JSONObject> searchLinkList(String index, List<String> idList) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.searchLinkList(idList); } @Override public List<JSONObject> searchDavNodeList(String index, List<String> idList) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.searchDavNodeList(idList); } /** * Link Document生成に伴い、Adsの一括登録用のレコード生成を行う. * @param index index * @param bulkRequestList 一括登録するLinkDocHandlerのリスト * @throws AdsException 同期失敗時発生。(処理結果が1件でない場合にも発生する) */ @Override public void bulkCreateLink(String index, List<LinkDocHandler> bulkRequestList) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.bulkCreateLink(bulkRequestList); } @Override public List<JSONObject> getLinkList(String index, long offset, long size) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.getLinkList(offset, size); } @Override public long countDavNode(String index) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.countDavNode(); } @Override public List<JSONObject> getDavNodeList(String index, long offset, long size) throws AdsException { IndexPeer ip = this.getIndexPeer(index); return ip.getDavNodeList(offset, size); } @Override public void deleteCellResourceFromEntity(String index, String cellId) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.deleteCellResourceFromEntity(cellId); } @Override public void deleteCellResourceFromDavNode(String index, String cellId) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.deleteCellResourceFromDavNode(cellId); } @Override public void deleteCellResourceFromLink(String index, String cellId) throws AdsException { IndexPeer ip = this.getIndexPeer(index); ip.deleteCellResourceFromLink(cellId); } @Override public void insertCellDeleteRecord(String dbName, String cellId) throws AdsException { IndexPeer ip = this.getIndexPeer(MANAGEMENT_DB_NAME); ip.insertCellDeleteRecord(dbName, cellId); } @Override public void createIndex(String index) throws AdsException { Connection con = null; Statement stmt = null; try { con = ds.getConnection(); stmt = con.createStatement(); int res = stmt.executeUpdate(Sql.createSchema.replace(SCHEMA_NAME_REPLACING_KEY, index)); log.debug("create schema:" + res); res = stmt.executeUpdate(Sql.createTableEntity.replace(SCHEMA_NAME_REPLACING_KEY, index)); log.debug("create table entity:" + res); res = stmt.executeUpdate(Sql.createTableLink.replace(SCHEMA_NAME_REPLACING_KEY, index)); log.debug("create table Link:" + res); res = stmt.executeUpdate(Sql.createTableDavNode.replace(SCHEMA_NAME_REPLACING_KEY, index)); log.debug("create table DavNode:" + res); res = stmt.executeUpdate(Sql.createTableCell.replace(SCHEMA_NAME_REPLACING_KEY, index)); log.debug("create table cell:" + res); } catch (SQLException e) { throw new AdsException(e); } finally { try { if (stmt != null) { stmt.close(); } if (con != null) { con.close(); } } catch (SQLException e) { throw new AdsException(e); } } } /** * 管理用DBを作成する. * @throws AdsException 管理用DB作成に失敗 */ public void createManagementDatabase() throws AdsException { Connection con = null; Statement stmt = null; try { con = ds.getConnection(); stmt = con.createStatement(); stmt.executeUpdate(Sql.createSchema.replace(SCHEMA_NAME_REPLACING_KEY, MANAGEMENT_DB_NAME)); stmt.executeUpdate( Sql.createManagementTableCellDelete.replace(SCHEMA_NAME_REPLACING_KEY, MANAGEMENT_DB_NAME)); } catch (SQLException e) { throw new AdsException(e); } finally { try { if (stmt != null) { stmt.close(); } if (con != null) { con.close(); } } catch (SQLException e) { throw new AdsException(e); } } } @Override public void deleteIndex(String index) throws AdsException { Connection con = null; Statement stmt = null; try { con = ds.getConnection(); stmt = con.createStatement(); int res = stmt.executeUpdate(Sql.dropSchema.replace(SCHEMA_NAME_REPLACING_KEY, index)); log.debug("delete schema:" + res); stmt.close(); con.close(); } catch (SQLException e) { throw new AdsException(e); } finally { try { if (stmt != null) { stmt.close(); } if (con != null) { con.close(); } } catch (SQLException e) { throw new AdsException(e); } } } IndexPeer getIndexPeer(final String index) { IndexPeer ip = this.peersMap.get(index); if (ip != null) { return ip; } ip = new IndexPeer(ds, index); this.peersMap.put(index, ip); return ip; } /** * Indexに対応するオブジェクト. */ static class IndexPeer { DataSource ds; String index; String sqlEntityInsert; String sqlEntityUpdate; String sqlEntityDelete; String sqlEntityBulkInsert; String sqlCellInsert; String sqlCellUpdate; String sqlCellDelete; String sqlLinkInsert; String sqlLinkUpdate; String sqlLinkDelete; String sqlDavNodeInsert; String sqlDavNodeUpdate; String sqlDavNodeDelete; String sqlDavBulkInsert; String sqlDeleteCellResourceFromEntity; String sqlDeleteCellResourceFromDavNode; String sqlDeleteCellResourceFromLink; String sqlCountCellResourceFromEntity; String sqlCountCellResourceFromDavNode; String sqlCountCellResourceFromLink; String sqlEntitySelect; String sqlEntityCount; String sqlCellSelect; String sqlCellCount; String sqlLinkSelect; String sqlLinkCount; String sqlLinkBulkInsert; String sqlDavNodeSelect; String sqlDavNodeCount; String sqlEntitySearch; String sqlCellSearch; String sqlLinkSearch; String sqlDavNodeSearch; // 管理DB用SQL群 String sqlCellDeleteInsert; static final StatementHandler NOP_STATEMENT_HANDLER = new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { writeLog(stmt); } }; static final QueryResultHandler QUERY_RESULT_HANDLER_FOR_COUNT = new QueryResultHandler() { @Override public Object handle(ResultSet resultSet) throws AdsException { try { if (!resultSet.next()) { throw new AdsException("No row was returened while 1 row is expected to be returned."); } return resultSet.getLong(1); } catch (SQLException e) { throw new AdsException(e); } } @Override public Object handleQueryIsEmpty() throws AdsException { throw new AdsException("No row was returened while 1 row is expected to be returned."); } }; IndexPeer(DataSource ds, String index) { this.ds = ds; this.index = index; this.sqlEntityInsert = Sql.insertEntity.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlEntityUpdate = Sql.updateEntity.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlEntityDelete = Sql.deleteEntity.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlEntityBulkInsert = Sql.bulkInsertEntity.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlCellInsert = Sql.insertCell.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlCellUpdate = Sql.updateCell.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlCellDelete = Sql.deleteCell.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlLinkInsert = Sql.insertLink.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlLinkBulkInsert = Sql.bulkInsertLink.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlLinkUpdate = Sql.updateLink.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlLinkDelete = Sql.deleteLink.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlDavNodeInsert = Sql.insertDavNode.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlDavNodeUpdate = Sql.updateDavNode.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlDavNodeDelete = Sql.deleteDavNode.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlDavBulkInsert = Sql.bulkInsertDav.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlDeleteCellResourceFromEntity = Sql.deleteCellResourceFromEntity .replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlDeleteCellResourceFromDavNode = Sql.deleteCellResourceFromDavNode .replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlDeleteCellResourceFromLink = Sql.deleteCellResourceFromLink .replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlCountCellResourceFromEntity = Sql.countCellResourceFromEntity .replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlCountCellResourceFromDavNode = Sql.countCellResourceFromDavNode .replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlCountCellResourceFromLink = Sql.countCellResourceFromLink .replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlEntitySelect = Sql.selectEntity.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlEntityCount = Sql.countEntity.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlCellSelect = Sql.selectCell.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlCellCount = Sql.countCell.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlLinkSelect = Sql.selectLink.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlLinkCount = Sql.countLink.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlDavNodeSelect = Sql.selectDav.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlDavNodeCount = Sql.countDav.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlEntitySearch = Sql.searchEntity.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlCellSearch = Sql.searchCell.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlLinkSearch = Sql.searchLink.replace(SCHEMA_NAME_REPLACING_KEY, this.index); this.sqlDavNodeSearch = Sql.searchDav.replace(SCHEMA_NAME_REPLACING_KEY, this.index); // 管理DB用SQL群 this.sqlCellDeleteInsert = Sql.insertCellDelete.replace(SCHEMA_NAME_REPLACING_KEY, this.index); } void createEntity(final EntitySetDocHandler oedh) throws AdsException { this.executeUpdateSql(this.sqlEntityInsert, new StatementHandlerForEntity(oedh)); } void updateEntity(final EntitySetDocHandler oedh) throws AdsException { this.executeUpdateSql(this.sqlEntityUpdate, new StatementHandlerForEntity(oedh)); } void deleteEntity(final String id) throws AdsException { this.executeUpdateSql(this.sqlEntityDelete, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(1, id); writeLog(stmt); } }); } void bulkEntity(final List<EntitySetDocHandler> bulkRequestList) throws AdsException { // 一括登録のSQLを生成する StringBuilder sql = new StringBuilder(this.sqlEntityBulkInsert); for (int i = 0; i < bulkRequestList.size(); i++) { sql.append("(?,?,?,?,?,?,?,?,?,?,?,?)"); if (i != bulkRequestList.size() - 1) { sql.append(","); } } this.executeUpdateSql(sql.toString(), new StatementHandlerForBulkEntity(bulkRequestList), bulkRequestList.size()); } void bulkUpdateEntityLink(final List<EntitySetDocHandler> bulkRequestList) throws AdsException { // 一括更新のSQLを生成する StringBuilder sql = new StringBuilder(this.sqlEntityBulkInsert); for (int i = 0; i < bulkRequestList.size(); i++) { sql.append("(?,?,?,?,?,?,?,?,?,?,?,?)"); if (i != bulkRequestList.size() - 1) { sql.append(","); } } sql.append(" on duplicate key update "); sql.append("links=values(links)"); int expectedUpdateCount = bulkRequestList.size() * 2; this.executeUpdateSql(sql.toString(), new StatementHandlerForBulkEntity(bulkRequestList), expectedUpdateCount); } void bulkUpdateDav(List<DavNode> bulkRequestList) throws AdsException { // 一括更新のSQLを生成する StringBuilder sql = new StringBuilder(this.sqlDavBulkInsert); for (int i = 0; i < bulkRequestList.size(); i++) { sql.append("(?,?,?,?,?,?,?,?,?,?,?)"); if (i != bulkRequestList.size() - 1) { sql.append(","); } } sql.append(" on duplicate key update "); sql.append("cell_id=values(cell_id)"); sql.append(",box_id=values(box_id)"); sql.append(",parent_id=values(parent_id)"); sql.append(",children=values(children)"); sql.append(",node_type=values(node_type)"); sql.append(",acl=values(acl)"); sql.append(",properties=values(properties)"); sql.append(",file=values(file)"); sql.append(",published=values(published)"); sql.append(",updated=values(updated)"); sql.append(",id=values(id)"); int expectedUpdateCount = bulkRequestList.size() * 2; this.executeUpdateSql(sql.toString(), new StatementHandlerForBulkDav(bulkRequestList), expectedUpdateCount); } void bulkCreateLink(final List<LinkDocHandler> bulkRequestList) throws AdsException { // 一括登録のSQLを生成する StringBuilder sql = new StringBuilder(this.sqlLinkBulkInsert); for (int i = 0; i < bulkRequestList.size(); i++) { sql.append("(?,?,?,?,?,?,?,?,?,?)"); if (i != bulkRequestList.size() - 1) { sql.append(","); } } this.executeUpdateSql(sql.toString(), new StatementHandlerForBulkLink(bulkRequestList), bulkRequestList.size()); } void createCell(final EntitySetDocHandler docHandler) throws AdsException { this.executeUpdateSql(this.sqlCellInsert, new StatementHandlerForCell(docHandler)); } void updateCell(final EntitySetDocHandler docHandler) throws AdsException { this.executeUpdateSql(this.sqlCellUpdate, new StatementHandlerForCell(docHandler)); } void deleteCell(final String id) throws AdsException { this.executeUpdateSql(this.sqlCellDelete, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(1, id); writeLog(stmt); } }); } void createLink(final LinkDocHandler ldh) throws AdsException { this.executeUpdateSql(this.sqlLinkInsert, new StatementHandlerForLink(ldh)); } void updateLink(final LinkDocHandler ldh) throws AdsException { this.executeUpdateSql(this.sqlLinkUpdate, new StatementHandlerForLink(ldh)); } void deleteLink(final String id) throws AdsException { this.executeUpdateSql(this.sqlLinkDelete, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(1, id); writeLog(stmt); } }); } void createDavNode(final DavNode davNode) throws AdsException { this.executeUpdateSql(this.sqlDavNodeInsert, new StatementHandlerForDavNode(davNode)); } void updateDavNode(final DavNode davNode) throws AdsException { this.executeUpdateSql(this.sqlDavNodeUpdate, new StatementHandlerForDavNode(davNode)); } void deleteDavNode(final String id) throws AdsException { this.executeUpdateSql(this.sqlDavNodeDelete, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(1, id); writeLog(stmt); } }); } void deleteCellResourceFromEntity(final String cellId) throws AdsException { this.executeDeleteByQuerySql(this.sqlDeleteCellResourceFromEntity, this.sqlCountCellResourceFromEntity, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(1, cellId); writeLog(stmt); } }); } void deleteCellResourceFromDavNode(final String cellId) throws AdsException { this.executeDeleteByQuerySql(this.sqlDeleteCellResourceFromDavNode, this.sqlCountCellResourceFromDavNode, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(1, cellId); writeLog(stmt); } }); } void deleteCellResourceFromLink(final String cellId) throws AdsException { this.executeDeleteByQuerySql(this.sqlDeleteCellResourceFromLink, this.sqlCountCellResourceFromLink, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(1, cellId); writeLog(stmt); } }); } void insertCellDeleteRecord(String dbName, String cellId) throws AdsException { String[] tableNames = {"ENTITY", "LINK", "DAV_NODE" }; for (String tableName : tableNames) { this.executeUpdateSql(this.sqlCellDeleteInsert, new StatementHandlerForCellDelete(dbName, tableName, cellId)); } } Long countEntity() throws AdsException { Object ret = this.executeQuerySql( this.sqlEntityCount, NOP_STATEMENT_HANDLER, QUERY_RESULT_HANDLER_FOR_COUNT); return (Long) ret; } Long countCell() throws AdsException { Object ret = this.executeQuerySql( this.sqlCellCount, NOP_STATEMENT_HANDLER, QUERY_RESULT_HANDLER_FOR_COUNT); return (Long) ret; } Long countLink() throws AdsException { Object ret = this.executeQuerySql( this.sqlLinkCount, NOP_STATEMENT_HANDLER, QUERY_RESULT_HANDLER_FOR_COUNT); return (Long) ret; } Long countDavNode() throws AdsException { Object ret = this.executeQuerySql( this.sqlDavNodeCount, NOP_STATEMENT_HANDLER, QUERY_RESULT_HANDLER_FOR_COUNT); return (Long) ret; } @SuppressWarnings("unchecked") List<JSONObject> getEntityList(final long offset, final long size) throws AdsException { Object ret = this.executeQuerySql( this.sqlEntitySelect, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setLong(1, offset); stmt.setLong(2, size); } }, createEntityQueryResultHandler()); return (List<JSONObject>) ret; } private QueryResultHandler createEntityQueryResultHandler() { return new QueryResultHandler() { @Override public Object handle(ResultSet resultSet) throws AdsException { try { List<JSONObject> ret = new ArrayList<JSONObject>(); while (resultSet.next()) { ret.add(getEntityJsonObject(resultSet)); } return ret; } catch (SQLException e) { throw new AdsException(e); } } @Override public Object handleQueryIsEmpty() throws AdsException { return new ArrayList<JSONObject>(); } }; } @SuppressWarnings("unchecked") private JSONObject getEntityJsonObject(ResultSet resultSet) throws SQLException { JSONObject json = new JSONObject(); json.put("type", resultSet.getString(Sql.IDX_ENTITY_TYPE)); json.put("id", resultSet.getString(Sql.NUMCOLS_ENTITY)); JSONObject source = new JSONObject(); json.put("source", source); source.put(OEntityDocHandler.KEY_CELL_ID, resultSet.getString(Sql.IDX_ENTITY_CELL_ID)); source.put(OEntityDocHandler.KEY_BOX_ID, resultSet.getString(Sql.IDX_ENTITY_BOX_ID)); source.put(OEntityDocHandler.KEY_NODE_ID, resultSet.getString(Sql.IDX_ENTITY_NODE_ID)); source.put(OEntityDocHandler.KEY_ENTITY_ID, resultSet.getString(Sql.IDX_ENTITY_ENTITY_ID)); source.put(OEntityDocHandler.KEY_STATIC_FIELDS, resultSet.getString(Sql.IDX_ENTITY_DECLARED_PROPS)); source.put(OEntityDocHandler.KEY_DYNAMIC_FIELDS, resultSet.getString(Sql.IDX_ENTITY_DYNAMIC_PROPS)); source.put(OEntityDocHandler.KEY_HIDDEN_FIELDS, resultSet.getString(Sql.IDX_ENTITY_HIDDEN_FIELDS)); source.put(OEntityDocHandler.KEY_LINK, resultSet.getString(Sql.IDX_ENTITY_LINKS)); source.put(OEntityDocHandler.KEY_PUBLISHED, resultSet.getString(Sql.IDX_ENTITY_PUBLISHED)); source.put(OEntityDocHandler.KEY_UPDATED, resultSet.getString(Sql.IDX_ENTITY_UPDATED)); return json; } @SuppressWarnings("unchecked") List<JSONObject> getCellList(final long offset, final long size) throws AdsException { Object ret = this.executeQuerySql( this.sqlCellSelect, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setLong(1, offset); stmt.setLong(2, size); } }, createCellQueryResultHandler()); return (List<JSONObject>) ret; } private QueryResultHandler createCellQueryResultHandler() { return new QueryResultHandler() { @Override public Object handle(ResultSet resultSet) throws AdsException { try { List<JSONObject> ret = new ArrayList<JSONObject>(); while (resultSet.next()) { ret.add(getCellJsonObject(resultSet)); } return ret; } catch (SQLException e) { throw new AdsException(e); } } @Override public Object handleQueryIsEmpty() throws AdsException { return new ArrayList<JSONObject>(); } }; } @SuppressWarnings("unchecked") private JSONObject getCellJsonObject(ResultSet resultSet) throws SQLException { JSONObject json = new JSONObject(); json.put("type", resultSet.getString(Sql.IDX_CELL_TYPE)); json.put("id", resultSet.getString(Sql.NUMCOLS_CELL)); JSONObject source = new JSONObject(); json.put("source", source); source.put(CellDocHandler.KEY_CELL_ID, resultSet.getString(Sql.IDX_CELL_CELL_ID)); source.put(CellDocHandler.KEY_BOX_ID, resultSet.getString(Sql.IDX_CELL_BOX_ID)); source.put(CellDocHandler.KEY_NODE_ID, resultSet.getString(Sql.IDX_CELL_NODE_ID)); source.put(CellDocHandler.KEY_STATIC_FIELDS, resultSet.getString(Sql.IDX_CELL_DECLARED_PROPS)); source.put(CellDocHandler.KEY_DYNAMIC_FIELDS, resultSet.getString(Sql.IDX_CELL_DYNAMIC_PROPS)); source.put(CellDocHandler.KEY_HIDDEN_FIELDS, resultSet.getString(Sql.IDX_CELL_HIDDEN_FIELDS)); source.put(CellDocHandler.KEY_LINK, resultSet.getString(Sql.IDX_CELL_LINKS)); source.put(CellDocHandler.KEY_ACL_FIELDS, resultSet.getString(Sql.IDX_CELL_ACL_FIELDS)); source.put(CellDocHandler.KEY_PUBLISHED, resultSet.getString(Sql.IDX_CELL_PUBLISHED)); source.put(CellDocHandler.KEY_UPDATED, resultSet.getString(Sql.IDX_CELL_UPDATED)); return json; } @SuppressWarnings("unchecked") List<JSONObject> getLinkList(final long offset, final long size) throws AdsException { Object ret = this.executeQuerySql( this.sqlLinkSelect, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setLong(1, offset); stmt.setLong(2, size); writeLog(stmt); } }, createLinkQueryResultHandler()); return (List<JSONObject>) ret; } private QueryResultHandler createLinkQueryResultHandler() { return new QueryResultHandler() { @Override public Object handle(ResultSet resultSet) throws AdsException { try { List<JSONObject> ret = new ArrayList<JSONObject>(); while (resultSet.next()) { ret.add(getLinkJsonObject(resultSet)); } return ret; } catch (SQLException e) { throw new AdsException(e); } } @Override public Object handleQueryIsEmpty() throws AdsException { return new ArrayList<JSONObject>(); } }; } @SuppressWarnings("unchecked") private JSONObject getLinkJsonObject(ResultSet resultSet) throws SQLException { JSONObject json = new JSONObject(); json.put("type", "link"); json.put("id", resultSet.getString(Sql.NUMCOLS_LINK)); JSONObject source = new JSONObject(); json.put("source", source); // // LINK 操作 SQLの 項目数 // static final int NUMCOLS_LINK = 10; // // 各項目の順序 // static final int IDX_LINK_CELL_ID = 1; // static final int IDX_LINK_BOX_ID = 2; // static final int IDX_LINK_NODE_ID = 3; // static final int IDX_LINK_ENT1_TYPE = 4; // static final int IDX_LINK_ENT1_ID = 5; // static final int IDX_LINK_ENT2_TYPE = 6; // static final int IDX_LINK_ENT2_ID = 7; // static final int IDX_LINK_PUBLISHED = 8; // static final int IDX_LINK_UPDATED = 9; // source.put(LinkDocHandler.KEY_CELL_ID, resultSet.getString(Sql.IDX_LINK_CELL_ID)); source.put(LinkDocHandler.KEY_BOX_ID, resultSet.getString(Sql.IDX_LINK_BOX_ID)); source.put(LinkDocHandler.KEY_NODE_ID, resultSet.getString(Sql.IDX_LINK_NODE_ID)); source.put(LinkDocHandler.KEY_ENT1_TYPE, resultSet.getString(Sql.IDX_LINK_ENT1_TYPE)); source.put(LinkDocHandler.KEY_ENT1_ID, resultSet.getString(Sql.IDX_LINK_ENT1_ID)); source.put(LinkDocHandler.KEY_ENT2_TYPE, resultSet.getString(Sql.IDX_LINK_ENT2_TYPE)); source.put(LinkDocHandler.KEY_ENT2_ID, resultSet.getString(Sql.IDX_LINK_ENT2_ID)); source.put(OEntityDocHandler.KEY_PUBLISHED, resultSet.getString(Sql.IDX_LINK_PUBLISHED)); source.put(OEntityDocHandler.KEY_UPDATED, resultSet.getString(Sql.IDX_LINK_UPDATED)); return json; } @SuppressWarnings("unchecked") List<JSONObject> getDavNodeList(final long offset, final long size) throws AdsException { Object ret = this.executeQuerySql( this.sqlDavNodeSelect, new StatementHandler() { @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setLong(1, offset); stmt.setLong(2, size); writeLog(stmt); } }, createDavNodeQueryResultHandler() ); return (List<JSONObject>) ret; } private QueryResultHandler createDavNodeQueryResultHandler() { return new QueryResultHandler() { @Override public Object handle(ResultSet resultSet) throws AdsException { try { List<JSONObject> ret = new ArrayList<JSONObject>(); while (resultSet.next()) { ret.add(getDavNodeJsonObject(resultSet)); } return ret; } catch (SQLException e) { throw new AdsException(e); } } @Override public Object handleQueryIsEmpty() throws AdsException { return new ArrayList<JSONObject>(); } }; } @SuppressWarnings("unchecked") private JSONObject getDavNodeJsonObject(ResultSet resultSet) throws SQLException { JSONObject json = new JSONObject(); json.put("type", "dav"); json.put("id", resultSet.getString(Sql.NUMCOLS_DAVNODE)); JSONObject source = new JSONObject(); json.put("source", source); // // DAV_NODE 操作 SQLの 項目数 // static final int NUMCOLS_DAVNODE = 10; // // 各項目の順序 // static final int IDX_DAVNODE_CELL_ID = 1; // static final int IDX_DAVNODE_BOX_ID = 2; // static final int IDX_DAVNODE_PARENT = 3; // static final int IDX_DAVNODE_CHILDREN = 4; // static final int IDX_DAVNODE_NODE_TYPE = 5; // static final int IDX_DAVNODE_ACL = 6; // static final int IDX_DAVNODE_PROPERTIES = 7; // static final int IDX_DAVNODE_PUBLISHED = 8; // static final int IDX_DAVNODE_UPDATED = 9; source.put(DavNode.KEY_CELL_ID, resultSet.getString(Sql.IDX_DAVNODE_CELL_ID)); source.put(DavNode.KEY_BOX_ID, resultSet.getString(Sql.IDX_DAVNODE_BOX_ID)); source.put(DavNode.KEY_PARENT, resultSet.getString(Sql.IDX_DAVNODE_PARENT)); source.put(DavNode.KEY_CHILDREN, resultSet.getString(Sql.IDX_DAVNODE_CHILDREN)); source.put(DavNode.KEY_NODE_TYPE, resultSet.getString(Sql.IDX_DAVNODE_NODE_TYPE)); source.put(DavNode.KEY_ACL, resultSet.getString(Sql.IDX_DAVNODE_ACL)); source.put(DavNode.KEY_PROPS, resultSet.getString(Sql.IDX_DAVNODE_PROPERTIES)); source.put(DavNode.KEY_FILE, resultSet.getString(Sql.IDX_DAVNODE_FILE)); source.put(DavNode.KEY_PUBLISHED, resultSet.getString(Sql.IDX_DAVNODE_PUBLISHED)); source.put(DavNode.KEY_UPDATED, resultSet.getString(Sql.IDX_DAVNODE_UPDATED)); return json; } private String createSearchSqlQueryString(final String sql, final List<String> idList) { // uuidリストを使用した検索用SQLを作成する。 StringBuilder sqlbuf = new StringBuilder(sql + "("); for (int i = 0; i < idList.size(); i++) { sqlbuf.append("?"); if (i != idList.size() - 1) { sqlbuf.append(","); } } sqlbuf.append(")"); return sqlbuf.toString(); } @SuppressWarnings("unchecked") List<JSONObject> searchEntityList(final List<String> idList) throws AdsException { String sql = createSearchSqlQueryString(this.sqlEntitySearch, idList); Object ret = this.executeQuerySql(sql, new StatementHandlerForSearch(idList), createEntityQueryResultHandler()); return (List<JSONObject>) ret; } @SuppressWarnings("unchecked") List<JSONObject> searchCellList(final List<String> idList) throws AdsException { String sql = createSearchSqlQueryString(this.sqlCellSearch, idList); Object ret = this.executeQuerySql(sql, new StatementHandlerForSearch(idList), createCellQueryResultHandler()); return (List<JSONObject>) ret; } @SuppressWarnings("unchecked") List<JSONObject> searchLinkList(final List<String> idList) throws AdsException { String sql = createSearchSqlQueryString(this.sqlLinkSearch, idList); Object ret = this.executeQuerySql(sql, new StatementHandlerForSearch(idList), new QueryResultHandler() { @Override public Object handle(ResultSet resultSet) throws AdsException { try { List<JSONObject> ret = new ArrayList<JSONObject>(); while (resultSet.next()) { ret.add(getLinkJsonObject(resultSet)); } return ret; } catch (SQLException e) { throw new AdsException(e); } } @Override public Object handleQueryIsEmpty() throws AdsException { return new ArrayList<JSONObject>(); } }); return (List<JSONObject>) ret; } @SuppressWarnings("unchecked") List<JSONObject> searchDavNodeList(final List<String> idList) throws AdsException { String sql = createSearchSqlQueryString(this.sqlDavNodeSearch, idList); Object ret = this.executeQuerySql(sql, new StatementHandlerForSearch(idList), createDavNodeQueryResultHandler()); return (List<JSONObject>) ret; } Connection getConnection() throws AdsException { try { // 接続する。 Connection con = ds.getConnection(); // DBCP経由だと以下のようなデータベースの切り替えは うまくいかない模様。 // con.setSchema(index); // なのでDBの選択は個別のSQLに埋め込む設計としている。 return con; } catch (SQLException e) { DcCoreLog.Server.RDB_CONNECT_FAIL.params(e.getMessage()).reason(e).writeLog(); throw new AdsException(e); } } Object executeQuerySql(String sql, StatementHandler sp, QueryResultHandler queryResultHandler) throws AdsException { log.debug(sql); Connection con = this.getConnection(); PreparedStatement stmt = null; try { stmt = con.prepareStatement(sql); sp.handle(stmt); ResultSet rs = stmt.executeQuery(); if (!rs.next()) { return queryResultHandler.handleQueryIsEmpty(); } rs.beforeFirst(); return queryResultHandler.handle(rs); } catch (SQLException e) { DcCoreLog.Server.EXECUTE_QUERY_SQL_FAIL.params(e.getMessage()).reason(e).writeLog(); throw new AdsException(e); } finally { try { stmt.close(); con.close(); } catch (SQLException e) { DcCoreLog.Server.RDB_DISCONNECT_FAIL.params(e.getMessage()).reason(e).writeLog(); throw new AdsException(e); } } } void executeDeleteByQuerySql(String deleteSql, String countSql, StatementHandler sp) throws AdsException { Connection con = this.getConnection(); PreparedStatement stmt = null; try { stmt = con.prepareStatement(deleteSql); sp.handle(stmt); DcCoreLog.Server.JDBC_EXEC_SQL.params( ((DelegatingPreparedStatement) stmt).getDelegate().toString()).writeLog(); stmt.executeUpdate(); if (!AUTO_COMMIT) { con.commit(); } } catch (SQLException e) { throw new AdsException(e); } finally { try { stmt.close(); } catch (SQLException e) { DcCoreLog.Server.RDB_DISCONNECT_FAIL.params(e.getMessage()).reason(e).writeLog(); throw new AdsException(e); } } try { // 件数の確認 stmt = con.prepareStatement(countSql); sp.handle(stmt); ResultSet resultSet = stmt.executeQuery(); // NOPMD - PMDのバグのためチェックから除外 long count = 0; if (resultSet.next()) { count = resultSet.getLong(1); } else { throw new AdsException("No row was returened while 1 row is expected to be returned."); } if (count != 0) { throw new AdsException(String.format( "[%d] rows have been affected while 0 row is expected to be affected.", count)); } } catch (SQLException e) { throw new AdsException(e); } finally { try { stmt.close(); con.close(); } catch (SQLException e) { DcCoreLog.Server.RDB_DISCONNECT_FAIL.params(e.getMessage()).reason(e).writeLog(); throw new AdsException(e); } } } void executeUpdateSql(String sql, StatementHandler sp) throws AdsException { executeUpdateSql(sql, sp, 1); } void executeUpdateSql(String sql, StatementHandler sp, int expectedCount) throws AdsException { Connection con = this.getConnection(); PreparedStatement stmt = null; try { stmt = con.prepareStatement(sql); sp.handle(stmt); int count = stmt.executeUpdate(); if (!AUTO_COMMIT) { con.commit(); } if (count != expectedCount) { throw new AdsException("[" + count + "] rows have been affected while " + expectedCount + " row is expected to be affected."); } } catch (SQLException e) { DcCoreLog.Server.JDBC_EXEC_SQL.params( ((DelegatingPreparedStatement) stmt).getDelegate().toString()).writeLog(); throw new AdsException(e); } finally { try { stmt.close(); con.close(); } catch (SQLException e) { DcCoreLog.Server.RDB_DISCONNECT_FAIL.params(e.getMessage()).reason(e).writeLog(); throw new AdsException(e); } } } /** * SQLのPreparedStatementを受け取ってプレースホルダに値を埋め込むHandler. */ abstract static class StatementHandler { abstract void handle(PreparedStatement stmt) throws SQLException; void writeLog(PreparedStatement stmt) { DcCoreLog.Server.JDBC_EXEC_SQL.params( ((DelegatingPreparedStatement) stmt).getDelegate().toString()).writeLog(); } } /** * Entityを扱うためのStatementHandler. */ static class StatementHandlerForEntity extends StatementHandler { EntitySetDocHandler oedh; StatementHandlerForEntity(EntitySetDocHandler oedh) { this.oedh = oedh; } @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(Sql.IDX_ENTITY_TYPE, oedh.getType()); stmt.setString(Sql.IDX_ENTITY_CELL_ID, oedh.getCellId()); stmt.setString(Sql.IDX_ENTITY_BOX_ID, oedh.getBoxId()); stmt.setString(Sql.IDX_ENTITY_NODE_ID, oedh.getNodeId()); stmt.setString(Sql.IDX_ENTITY_ENTITY_ID, oedh.getEntityTypeId()); stmt.setString(Sql.IDX_ENTITY_DECLARED_PROPS, this.oedh.getStaticFieldsString()); stmt.setString(Sql.IDX_ENTITY_DYNAMIC_PROPS, this.oedh.getDynamicFieldsString()); stmt.setString(Sql.IDX_ENTITY_HIDDEN_FIELDS, this.oedh.getHiddenFieldsString()); stmt.setString(Sql.IDX_ENTITY_LINKS, this.oedh.getManyToOnelinkIdString()); stmt.setLong(Sql.IDX_ENTITY_PUBLISHED, oedh.getPublished()); stmt.setLong(Sql.IDX_ENTITY_UPDATED, oedh.getUpdated()); stmt.setString(Sql.NUMCOLS_ENTITY, oedh.getId()); if (UserDataODataProducer.USER_ODATA_NAMESPACE.equals(oedh.getType())) { DcCoreLog.Server.JDBC_USER_ODATA_SQL.params(oedh.getUnitUserName(), "ENTITY", oedh.getId(), oedh.getType(), oedh.getCellId(), oedh.getBoxId(), oedh.getNodeId(), oedh.getEntityTypeId()).writeLog(); } else { writeLog(stmt); } } } /** * BulkEntityを扱うためのStatementHandler. */ static class StatementHandlerForBulkEntity extends StatementHandler { List<EntitySetDocHandler> bulkRequestList; StatementHandlerForBulkEntity(List<EntitySetDocHandler> bulkRequestList) { this.bulkRequestList = bulkRequestList; } @Override public void handle(PreparedStatement stmt) throws SQLException { int index = 1; for (EntitySetDocHandler docHandler : bulkRequestList) { stmt.setString(index++, docHandler.getType()); stmt.setString(index++, docHandler.getCellId()); stmt.setString(index++, docHandler.getBoxId()); stmt.setString(index++, docHandler.getNodeId()); stmt.setString(index++, docHandler.getEntityTypeId()); stmt.setString(index++, docHandler.getStaticFieldsString()); stmt.setString(index++, docHandler.getDynamicFieldsString()); stmt.setString(index++, docHandler.getHiddenFieldsString()); stmt.setString(index++, docHandler.getManyToOnelinkIdString()); stmt.setLong(index++, docHandler.getPublished()); stmt.setLong(index++, docHandler.getUpdated()); stmt.setString(index++, docHandler.getId()); } } } /** * BulkLinkを扱うためのStatementHandler. */ static class StatementHandlerForBulkLink extends StatementHandler { List<LinkDocHandler> bulkRequestList; StatementHandlerForBulkLink(List<LinkDocHandler> bulkRequestList) { this.bulkRequestList = bulkRequestList; } @Override public void handle(PreparedStatement stmt) throws SQLException { int index = 1; for (LinkDocHandler docHandler : bulkRequestList) { stmt.setString(index++, docHandler.getCellId()); stmt.setString(index++, docHandler.getBoxId()); stmt.setString(index++, docHandler.getNodeId()); stmt.setString(index++, docHandler.getEnt1Type()); stmt.setString(index++, docHandler.getEnt1Key()); stmt.setString(index++, docHandler.getEnt2Type()); stmt.setString(index++, docHandler.getEnt2Key()); stmt.setLong(index++, docHandler.getPublished()); stmt.setLong(index++, docHandler.getUpdated()); stmt.setString(index++, docHandler.getId()); } } } /** * CellEntityを扱うためのStatementHandler. */ static class StatementHandlerForCell extends StatementHandler { EntitySetDocHandler docHandler; StatementHandlerForCell(EntitySetDocHandler docHandler) { this.docHandler = docHandler; } @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(Sql.IDX_CELL_TYPE, docHandler.getType()); stmt.setString(Sql.IDX_CELL_CELL_ID, docHandler.getCellId()); stmt.setString(Sql.IDX_CELL_BOX_ID, docHandler.getBoxId()); stmt.setString(Sql.IDX_CELL_NODE_ID, docHandler.getNodeId()); stmt.setString(Sql.IDX_CELL_DECLARED_PROPS, docHandler.getStaticFieldsString()); stmt.setString(Sql.IDX_CELL_DYNAMIC_PROPS, docHandler.getDynamicFieldsString()); stmt.setString(Sql.IDX_CELL_HIDDEN_FIELDS, docHandler.getHiddenFieldsString()); stmt.setString(Sql.IDX_CELL_LINKS, docHandler.getManyToOnelinkIdString()); stmt.setString(Sql.IDX_CELL_ACL_FIELDS, JSONObject.toJSONString(docHandler.getAclFields())); stmt.setLong(Sql.IDX_CELL_PUBLISHED, docHandler.getPublished()); stmt.setLong(Sql.IDX_CELL_UPDATED, docHandler.getUpdated()); stmt.setString(Sql.NUMCOLS_CELL, docHandler.getId()); writeLog(stmt); } } /** * Linkを扱うためのStatementHandler. */ static class StatementHandlerForLink extends StatementHandler { LinkDocHandler ldh; StatementHandlerForLink(LinkDocHandler ldh) { this.ldh = ldh; } @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(Sql.IDX_LINK_CELL_ID, ldh.getCellId()); stmt.setString(Sql.IDX_LINK_BOX_ID, ldh.getBoxId()); stmt.setString(Sql.IDX_LINK_NODE_ID, ldh.getNodeId()); stmt.setString(Sql.IDX_LINK_ENT1_TYPE, ldh.getEnt1Type()); stmt.setString(Sql.IDX_LINK_ENT1_ID, ldh.getEnt1Key()); stmt.setString(Sql.IDX_LINK_ENT2_TYPE, ldh.getEnt2Type()); stmt.setString(Sql.IDX_LINK_ENT2_ID, ldh.getEnt2Key()); stmt.setLong(Sql.IDX_LINK_PUBLISHED, ldh.getPublished()); stmt.setLong(Sql.IDX_LINK_UPDATED, ldh.getUpdated()); stmt.setString(Sql.NUMCOLS_LINK, ldh.getId()); writeLog(stmt); } } /** * DavNodeを扱うためのStatementHandler. */ static class StatementHandlerForDavNode extends StatementHandler { DavNode davNode; StatementHandlerForDavNode(DavNode davNode) { this.davNode = davNode; } @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(Sql.IDX_DAVNODE_CELL_ID, davNode.getCellId()); stmt.setString(Sql.IDX_DAVNODE_BOX_ID, davNode.getBoxId()); stmt.setString(Sql.IDX_DAVNODE_PARENT, davNode.getParentId()); stmt.setString(Sql.IDX_DAVNODE_CHILDREN, JSONObject.toJSONString(davNode.getChildren())); stmt.setString(Sql.IDX_DAVNODE_NODE_TYPE, davNode.getNodeType()); stmt.setString(Sql.IDX_DAVNODE_ACL, JSONObject.toJSONString(davNode.getAcl())); stmt.setString(Sql.IDX_DAVNODE_PROPERTIES, JSONObject.toJSONString(davNode.getProperties())); String file = null; if (davNode.getFile() != null) { file = JSONObject.toJSONString(davNode.getFile()); } stmt.setString(Sql.IDX_DAVNODE_FILE, file); stmt.setLong(Sql.IDX_DAVNODE_PUBLISHED, davNode.getPublished()); stmt.setLong(Sql.IDX_DAVNODE_UPDATED, davNode.getUpdated()); stmt.setString(Sql.NUMCOLS_DAVNODE, davNode.getId()); writeLog(stmt); } } /** * BulkDavを扱うためのStatementHandler. */ static class StatementHandlerForBulkDav extends StatementHandler { List<DavNode> bulkRequestList; StatementHandlerForBulkDav(List<DavNode> bulkRequestList) { this.bulkRequestList = bulkRequestList; } @Override public void handle(PreparedStatement stmt) throws SQLException { int index = 1; for (DavNode docHandler : bulkRequestList) { stmt.setString(index++, docHandler.getCellId()); stmt.setString(index++, docHandler.getBoxId()); stmt.setString(index++, docHandler.getParentId()); stmt.setString(index++, JSONObject.toJSONString(docHandler.getChildren())); stmt.setString(index++, docHandler.getNodeType()); stmt.setString(index++, JSONObject.toJSONString(docHandler.getAcl())); stmt.setString(index++, JSONObject.toJSONString(docHandler.getProperties())); String file = null; if (docHandler.getFile() != null) { file = JSONObject.toJSONString(docHandler.getFile()); } stmt.setString(index++, file); stmt.setLong(index++, docHandler.getPublished()); stmt.setLong(index++, docHandler.getUpdated()); stmt.setString(index++, docHandler.getId()); } } } /** * セル削除管理を扱うためのStatementHandler. */ static class StatementHandlerForCellDelete extends StatementHandler { String dbName; String tableName; String cellId; StatementHandlerForCellDelete(String dbName, String tableName, String cellId) { this.dbName = dbName; this.tableName = tableName; this.cellId = cellId; } @Override public void handle(PreparedStatement stmt) throws SQLException { stmt.setString(Sql.IDX_CELL_DELETE_DB_NAME, dbName); stmt.setString(Sql.IDX_CELL_DELETE_TABLE_NAME, tableName); stmt.setString(Sql.IDX_CELL_DELETE_CELL_ID, cellId); writeLog(stmt); } } /** * Entityテーブルを検索するためのStatementHandler. */ static class StatementHandlerForSearch extends StatementHandler { List<String> idList; StatementHandlerForSearch(List<String> idList) { this.idList = idList; } @Override public void handle(PreparedStatement stmt) throws SQLException { int index = 1; for (String uuid : idList) { stmt.setString(index++, uuid); } } } /** * PreStatementに. */ interface QueryResultHandler { Object handleQueryIsEmpty() throws AdsException; Object handle(ResultSet resultSet) throws AdsException; } } /** * 使用するSQLのテンプレートをStaticで保持しておくクラス. */ static class Sql { static String createSchema = DcCoreUtils.readStringResource("es/ads/ddl-createschema.sql", CharEncoding.UTF_8); static String dropSchema = DcCoreUtils.readStringResource("es/ads/ddl-dropschema.sql", CharEncoding.UTF_8); static String createTableEntity = DcCoreUtils.readStringResource("es/ads/ddl-createtable-entity.sql", CharEncoding.UTF_8); static String createTableLink = DcCoreUtils.readStringResource("es/ads/ddl-createtable-link.sql", CharEncoding.UTF_8); static String createTableDavNode = DcCoreUtils.readStringResource("es/ads/ddl-createtable-davnode.sql", CharEncoding.UTF_8); static String createTableCell = DcCoreUtils.readStringResource("es/ads/ddl-createtable-cell.sql", CharEncoding.UTF_8); static String createManagementTableCellDelete = DcCoreUtils.readStringResource("es/ads/ddl-create-management-table-cell-delete.sql", CharEncoding.UTF_8); static String insertEntity = DcCoreUtils.readStringResource("es/ads/entity-insert.sql", CharEncoding.UTF_8); static String updateEntity = DcCoreUtils.readStringResource("es/ads/entity-update.sql", CharEncoding.UTF_8); static String deleteEntity = DcCoreUtils.readStringResource("es/ads/entity-delete.sql", CharEncoding.UTF_8); static String bulkInsertEntity = DcCoreUtils.readStringResource("es/ads/entity-bulk-insert.sql", CharEncoding.UTF_8); static String insertCell = DcCoreUtils.readStringResource("es/ads/cell-insert.sql", CharEncoding.UTF_8); static String updateCell = DcCoreUtils.readStringResource("es/ads/cell-update.sql", CharEncoding.UTF_8); static String deleteCell = DcCoreUtils.readStringResource("es/ads/cell-delete.sql", CharEncoding.UTF_8); static String insertLink = DcCoreUtils.readStringResource("es/ads/link-insert.sql", CharEncoding.UTF_8); static String updateLink = DcCoreUtils.readStringResource("es/ads/link-update.sql", CharEncoding.UTF_8); static String deleteLink = DcCoreUtils.readStringResource("es/ads/link-delete.sql", CharEncoding.UTF_8); static String bulkInsertLink = DcCoreUtils.readStringResource("es/ads/link-bulk-insert.sql", CharEncoding.UTF_8); static String insertDavNode = DcCoreUtils.readStringResource("es/ads/dav-insert.sql", CharEncoding.UTF_8); static String updateDavNode = DcCoreUtils.readStringResource("es/ads/dav-update.sql", CharEncoding.UTF_8); static String deleteDavNode = DcCoreUtils.readStringResource("es/ads/dav-delete.sql", CharEncoding.UTF_8); static String bulkInsertDav = DcCoreUtils.readStringResource("es/ads/dav-bulk-insert.sql", CharEncoding.UTF_8); static String deleteCellResourceFromEntity = DcCoreUtils.readStringResource("es/ads/delete-cellresource-from-entity.sql", CharEncoding.UTF_8); static String deleteCellResourceFromDavNode = DcCoreUtils.readStringResource("es/ads/delete-cellresource-from-davnode.sql", CharEncoding.UTF_8); static String deleteCellResourceFromLink = DcCoreUtils.readStringResource("es/ads/delete-cellresource-from-link.sql", CharEncoding.UTF_8); static String countCellResourceFromEntity = DcCoreUtils.readStringResource("es/ads/count-cellresource-from-entity.sql", CharEncoding.UTF_8); static String countCellResourceFromDavNode = DcCoreUtils.readStringResource("es/ads/count-cellresource-from-davnode.sql", CharEncoding.UTF_8); static String countCellResourceFromLink = DcCoreUtils.readStringResource("es/ads/count-cellresource-from-link.sql", CharEncoding.UTF_8); static String selectEntity = DcCoreUtils.readStringResource("es/ads/entity-select.sql", CharEncoding.UTF_8); static String countEntity = DcCoreUtils.readStringResource("es/ads/entity-count.sql", CharEncoding.UTF_8); static String selectCell = DcCoreUtils.readStringResource("es/ads/cell-select.sql", CharEncoding.UTF_8); static String countCell = DcCoreUtils.readStringResource("es/ads/cell-count.sql", CharEncoding.UTF_8); static String selectLink = DcCoreUtils.readStringResource("es/ads/link-select.sql", CharEncoding.UTF_8); static String countLink = DcCoreUtils.readStringResource("es/ads/link-count.sql", CharEncoding.UTF_8); static String selectDav = DcCoreUtils.readStringResource("es/ads/dav-select.sql", CharEncoding.UTF_8); static String countDav = DcCoreUtils.readStringResource("es/ads/dav-count.sql", CharEncoding.UTF_8); static String searchEntity = DcCoreUtils.readStringResource("es/ads/entity-search.sql", CharEncoding.UTF_8); static String searchCell = DcCoreUtils.readStringResource("es/ads/cell-search.sql", CharEncoding.UTF_8); static String searchLink = DcCoreUtils.readStringResource("es/ads/link-search.sql", CharEncoding.UTF_8); static String searchDav = DcCoreUtils.readStringResource("es/ads/dav-search.sql", CharEncoding.UTF_8); // Cell管理用SQL群 static String insertCellDelete = DcCoreUtils.readStringResource("es/ads/celldelete-insert.sql", CharEncoding.UTF_8); // ENTITY 操作 SQLの 項目数 static final int NUMCOLS_ENTITY = 12; // 各項目の順序 static final int IDX_ENTITY_TYPE = 1; static final int IDX_ENTITY_CELL_ID = 2; static final int IDX_ENTITY_BOX_ID = 3; static final int IDX_ENTITY_NODE_ID = 4; static final int IDX_ENTITY_ENTITY_ID = 5; static final int IDX_ENTITY_DECLARED_PROPS = 6; static final int IDX_ENTITY_DYNAMIC_PROPS = 7; static final int IDX_ENTITY_HIDDEN_FIELDS = 8; static final int IDX_ENTITY_LINKS = 9; static final int IDX_ENTITY_PUBLISHED = 10; static final int IDX_ENTITY_UPDATED = 11; // LINK 操作 SQLの 項目数 static final int NUMCOLS_LINK = 10; // 各項目の順序 static final int IDX_LINK_CELL_ID = 1; static final int IDX_LINK_BOX_ID = 2; static final int IDX_LINK_NODE_ID = 3; static final int IDX_LINK_ENT1_TYPE = 4; static final int IDX_LINK_ENT1_ID = 5; static final int IDX_LINK_ENT2_TYPE = 6; static final int IDX_LINK_ENT2_ID = 7; static final int IDX_LINK_PUBLISHED = 8; static final int IDX_LINK_UPDATED = 9; // DAV_NODE 操作 SQLの 項目数 static final int NUMCOLS_DAVNODE = 11; // 各項目の順序 static final int IDX_DAVNODE_CELL_ID = 1; static final int IDX_DAVNODE_BOX_ID = 2; static final int IDX_DAVNODE_PARENT = 3; static final int IDX_DAVNODE_CHILDREN = 4; static final int IDX_DAVNODE_NODE_TYPE = 5; static final int IDX_DAVNODE_ACL = 6; static final int IDX_DAVNODE_PROPERTIES = 7; static final int IDX_DAVNODE_FILE = 8; static final int IDX_DAVNODE_PUBLISHED = 9; static final int IDX_DAVNODE_UPDATED = 10; // ENTITY 操作 SQLの 項目数 static final int NUMCOLS_CELL = 12; // 各項目の順序 static final int IDX_CELL_TYPE = 1; static final int IDX_CELL_CELL_ID = 2; static final int IDX_CELL_BOX_ID = 3; static final int IDX_CELL_NODE_ID = 4; static final int IDX_CELL_DECLARED_PROPS = 5; static final int IDX_CELL_DYNAMIC_PROPS = 6; static final int IDX_CELL_HIDDEN_FIELDS = 7; static final int IDX_CELL_LINKS = 8; static final int IDX_CELL_ACL_FIELDS = 9; static final int IDX_CELL_PUBLISHED = 10; static final int IDX_CELL_UPDATED = 11; // CELL_DELETE 操作 SQLの 項目 static final int IDX_CELL_DELETE_DB_NAME = 1; static final int IDX_CELL_DELETE_TABLE_NAME = 2; static final int IDX_CELL_DELETE_CELL_ID = 3; } }