All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jodd.db.oom.sqlgen.chunks.ColumnsSelectChunk Maven / Gradle / Ivy

Go to download

Jodd DB is efficient and thin database facade; DbOom is convenient database object mapper.

There is a newer version: 6.0.0
Show newest version
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

package jodd.db.oom.sqlgen.chunks;

import jodd.db.oom.ColumnAliasType;
import jodd.db.oom.DbEntityColumnDescriptor;
import jodd.db.oom.DbEntityDescriptor;
import jodd.db.oom.DbEntityManager;
import jodd.db.oom.sqlgen.DbSqlBuilderException;
import jodd.db.oom.sqlgen.TemplateData;
import jodd.util.ArraysUtil;
import jodd.util.StringPool;
import jodd.util.StringUtil;

/**
 * Columns select chunk resolves entity column(s) from column references. Should be used for SELECT queries.
 * 

* Column reference is specified as: {@link TableChunk tableReference}.propertyName where property name is * a property of the entity references by table reference. Result is rendered as: * tableName.column or alias.column (if table has an alias). *

* There are some special values for propertyName *

    *
  • wildcard (*), all table columns will be listed
  • *
  • id sign (+), all table id columns will be listed
  • *
*

* If previous chunk is also a column chunk, comma separator will be added in between. *

* Note that column alias are appended to the column name (using 'as' construct). *

* Macro rules: *

    *
  • $C{tableRef} is rendered as FOO.col1, FOO.col2,...
  • *
  • $C{tableRef.*} is equal to above, renders all entity columns
  • *
  • $C{tableRef.+} renders to only identity columns
  • *
  • $C{tableRef.%} renders all but identity columns
  • *
  • $C{tableRef.colRef} is rendered as FOO.column
  • *
  • $C{tableRef.[colRef1,colRef2|...]} is rendered as FOO.column1, FOO.column2,..., support id sign (+)
  • *
  • $C{entityRef.colRef} renders to FOO$column
  • *
  • $C{hint.entityRef...} defines a hint
  • *
  • $C{hint:entityRef...} defines a hint with custom name
  • *
  • $C{.columName} renders as column name
  • *
  • $C{hint:.columName} renders as column name and defines its hint
  • *
*/ public class ColumnsSelectChunk extends SqlChunk { private static final String AS = " as "; private static final char SPLIT = ','; protected final String tableRef; protected final String columnRef; protected final String[] columnRefArr; protected final int includeColumns; protected final String hint; protected final String columnAliasSeparator; private ColumnsSelectChunk( final DbEntityManager dbEntityManager, final String columnAliasSeparator, final String tableRef, final String columnRef, final String[] columnRefArr, final int includeColumns, final String hint) { super(dbEntityManager, CHUNK_SELECT_COLUMNS); this.columnAliasSeparator = columnAliasSeparator; this.tableRef = tableRef; this.columnRef = columnRef; this.columnRefArr = columnRefArr; this.includeColumns = includeColumns; this.hint = hint; } public ColumnsSelectChunk(final DbEntityManager dbEntityManager, final String columnAliasSeparator, final String tableRef, final String columnRef) { this(dbEntityManager, columnAliasSeparator, tableRef, columnRef, null, COLS_NA, null); } public ColumnsSelectChunk(final DbEntityManager dbEntityManager, final String columnAliasSeparator, final String tableRef, final String... columnRefArr) { this(dbEntityManager, columnAliasSeparator, tableRef, null, columnRefArr, COLS_NA_MULTI, null); } public ColumnsSelectChunk(final DbEntityManager dbEntityManager, final String columnAliasSeparator, final String tableRef, final boolean includeAll) { this(dbEntityManager, columnAliasSeparator, tableRef, null, null, includeAll ? COLS_ALL : COLS_ONLY_IDS, null); } public ColumnsSelectChunk(final DbEntityManager dbEntityManager, final String columnAliasSeparator, String reference) { super(dbEntityManager, CHUNK_SELECT_COLUMNS); reference = reference.trim(); int dotNdx = reference.lastIndexOf('.'); if (dotNdx == -1) { this.tableRef = reference; this.columnRef = null; this.columnRefArr = null; this.includeColumns = COLS_ALL; this.hint = null; } else { final String tref = reference.substring(0, dotNdx); reference = reference.substring(dotNdx + 1); // table dotNdx = tref.lastIndexOf('.'); if (dotNdx == -1) { this.tableRef = tref; this.hint = null; } else { final int doubleColumnNdx = tref.indexOf(':'); if (doubleColumnNdx == -1) { // no special hint this.tableRef = tref.substring(dotNdx + 1); this.hint = tref; } else { // hint is different this.tableRef = tref.substring(doubleColumnNdx + 1); this.hint = tref.substring(0, doubleColumnNdx); } } // column if (reference.equals(StringPool.STAR)) { this.columnRef = null; this.columnRefArr = null; this.includeColumns = COLS_ALL; } else if (reference.equals(StringPool.PLUS)) { this.columnRef = null; this.columnRefArr = null; this.includeColumns = COLS_ONLY_IDS; } else if (reference.equals(StringPool.PERCENT)) { this.columnRef = null; this.columnRefArr = null; this.includeColumns = COLS_ALL_BUT_ID; } else if ( reference.length() != 0 && reference.charAt(0) == '[' && reference.charAt(reference.length() - 1) == ']') { this.columnRef = null; this.columnRefArr = StringUtil.splitc(reference.substring(1, reference.length() - 1), SPLIT); StringUtil.trimAll(this.columnRefArr); this.includeColumns = COLS_NA_MULTI; } else { this.columnRef = reference; this.columnRefArr = null; this.includeColumns = COLS_NA; } } this.columnAliasSeparator = columnAliasSeparator; } // ---------------------------------------------------------------- process /** * Counts actual real hints. */ @Override public void init(final TemplateData templateData) { super.init(templateData); if (hint != null) { templateData.incrementHintsCount(); } } @Override public void process(final StringBuilder out) { // hints if (templateData.hasHints()) { templateData.registerHint(hint == null ? tableRef : hint); } // columns separateByCommaOrSpace(out); // special case, only column name, no table ref/name if (tableRef.length() == 0) { out.append(columnRef); return; } boolean useTableReference = true; DbEntityDescriptor ded = lookupTableRef(tableRef, false); if (ded == null) { useTableReference = false; ded = lookupName(tableRef); } if (columnRef == null) { final DbEntityColumnDescriptor[] decList = ded.getColumnDescriptors(); int count = 0; final boolean withIds = (columnRefArr != null) && ArraysUtil.contains(columnRefArr, StringPool.PLUS); for (final DbEntityColumnDescriptor dec : decList) { if ((includeColumns == COLS_ONLY_IDS) && (!dec.isId())) { continue; } if ((includeColumns == COLS_ALL_BUT_ID) && (dec.isId())) { continue; } if ((includeColumns == COLS_NA_MULTI) && (!withIds || (!dec.isId())) && (!ArraysUtil.contains(columnRefArr, dec.getPropertyName()))) { continue; } if (count > 0) { out.append(',').append(' '); } templateData.lastColumnDec = dec; if (useTableReference) { appendColumnName(out, ded, dec); } else { appendAlias(out, ded, dec); } count++; } } else { final DbEntityColumnDescriptor dec = ded.findByPropertyName(columnRef); if (dec == null) { throw new DbSqlBuilderException("Invalid column reference: [" + tableRef + '.' + columnRef + "]"); } templateData.lastColumnDec = dec; if (useTableReference) { appendColumnName(out, ded, dec); } else { appendAlias(out, ded, dec); } } } /** * Appends alias. */ protected void appendAlias(final StringBuilder query, final DbEntityDescriptor ded, final DbEntityColumnDescriptor dec) { final ColumnAliasType columnAliasType = templateData.getColumnAliasType(); if (columnAliasType == null || columnAliasType == ColumnAliasType.TABLE_REFERENCE) { final String tableName = ded.getTableName(); final String columnName = dec.getColumnNameForQuery(); templateData.registerColumnDataForTableRef(tableRef, tableName); query.append(tableRef).append(columnAliasSeparator).append(columnName); } else if (columnAliasType == ColumnAliasType.COLUMN_CODE) { final String tableName = ded.getTableName(); final String columnName = dec.getColumnName(); final String code = templateData.registerColumnDataForColumnCode(tableName, columnName); query.append(code); } else if (columnAliasType == ColumnAliasType.TABLE_NAME) { final String tableName = ded.getTableNameForQuery(); final String columnName = dec.getColumnNameForQuery(); query.append(tableName).append(columnAliasSeparator).append(columnName); } } /** * Simply appends column name with optional table reference and alias. */ protected void appendColumnName(final StringBuilder query, final DbEntityDescriptor ded, final DbEntityColumnDescriptor dec) { query.append(resolveTable(tableRef, ded)).append('.').append(dec.getColumnName()); if (templateData.getColumnAliasType() != null) { // create column aliases query.append(AS); switch (templateData.getColumnAliasType()) { case TABLE_NAME: { final String tableName = ded.getTableNameForQuery(); query.append(tableName).append(columnAliasSeparator).append(dec.getColumnNameForQuery()); break; } case TABLE_REFERENCE: { final String tableName = ded.getTableName(); templateData.registerColumnDataForTableRef(tableRef, tableName); query.append(tableRef).append(columnAliasSeparator).append(dec.getColumnNameForQuery()); break; } case COLUMN_CODE: { final String tableName = ded.getTableName(); final String code = templateData.registerColumnDataForColumnCode(tableName, dec.getColumnName()); query.append(code); break; } } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy