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.DbEntityDescriptor;
import jodd.db.oom.DbEntityColumnDescriptor;
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 ColumnsSelectChunk(String tableRef, String columnRef,String[] columnRefArr, int includeColumns, String hint) { super(CHUNK_SELECT_COLUMNS); this.tableRef = tableRef; this.columnRef = columnRef; this.columnRefArr = columnRefArr; this.includeColumns = includeColumns; this.hint = hint; } public ColumnsSelectChunk(String tableRef, String columnRef) { this(tableRef, columnRef, null, COLS_NA, null); } public ColumnsSelectChunk(String tableRef, String... columnRefArr) { this(tableRef, null, columnRefArr, COLS_NA_MULTI, null); } public ColumnsSelectChunk(String tableRef, boolean includeAll) { this(tableRef, null, null, includeAll ? COLS_ALL : COLS_ONLY_IDS, null); } public ColumnsSelectChunk(String reference) { super(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 { 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 { 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; } } } // ---------------------------------------------------------------- process /** * Counts actual real hints. */ @Override public void init(TemplateData templateData) { super.init(templateData); if (hint != null) { templateData.incrementHintsCount(); } } @Override public void process(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) { DbEntityColumnDescriptor[] decList = ded.getColumnDescriptors(); int count = 0; boolean withIds = (columnRefArr != null) && ArraysUtil.contains(columnRefArr, StringPool.PLUS); for (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.getColumnName()); } else { appendAlias(out, ded, dec.getColumnName()); } count++; } } else { DbEntityColumnDescriptor dec = ded.findByPropertyName(columnRef); templateData.lastColumnDec = dec; String columnName = dec == null ? null : dec.getColumnName(); //String columnName = ded.getColumnName(columnRef); if (columnName == null) { throw new DbSqlBuilderException("Invalid column reference: " + tableRef + '.' + columnRef); } if (useTableReference) { appendColumnName(out, ded, columnName); } else { appendAlias(out, ded, columnName); } } } /** * Appends alias. */ protected void appendAlias(StringBuilder query, DbEntityDescriptor ded, String column) { String tableName = ded.getTableName(); ColumnAliasType columnAliasType = templateData.getColumnAliasType(); String columnAliasSeparator = templateData.getDbOomManager().getColumnAliasSeparator(); if (columnAliasType == null || columnAliasType == ColumnAliasType.TABLE_REFERENCE) { templateData.registerColumnDataForTableRef(tableRef, tableName); query.append(tableRef).append(columnAliasSeparator).append(column); } else if (columnAliasType == ColumnAliasType.COLUMN_CODE) { String code = templateData.registerColumnDataForColumnCode(tableName, column); query.append(code); } else if (columnAliasType == ColumnAliasType.TABLE_NAME) { query.append(tableName).append(columnAliasSeparator).append(column); } } /** * Simply appends column name with optional table reference and alias. */ protected void appendColumnName(StringBuilder query, DbEntityDescriptor ded, String column) { query.append(resolveTable(tableRef, ded)).append('.').append(column); if (templateData.getColumnAliasType() != null) { // create column aliases String tableName = ded.getTableName(); query.append(AS); switch (templateData.getColumnAliasType()) { case TABLE_NAME: query.append(tableName).append(templateData.getDbOomManager().getColumnAliasSeparator()).append(column); break; case TABLE_REFERENCE: templateData.registerColumnDataForTableRef(tableRef, tableName); query.append(tableRef).append(templateData.getDbOomManager().getColumnAliasSeparator()).append(column); break; case COLUMN_CODE: String code = templateData.registerColumnDataForColumnCode(tableName, column); query.append(code); break; } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy