Commit a6119cf9 authored by Asier Lostalé's avatar Asier Lostalé
Browse files

fixed FR-44155: support full text search in PostgreSQL

MR !88
parents 6e413f3e 59df028e
......@@ -52,10 +52,11 @@ public class CachedPreference implements Serializable {
public static final String ALLOW_UNSECURED_DS_REQUEST = "OBSERDS_AllowUnsecuredDatasourceRequest";
public static final String ALLOW_WHERE_PARAMETER = "OBSERDS_AllowWhereParameter";
public static final String RESTRICT_ERP_ACCESS_IN_STORE_SERVER = "RestrictErpAccessInStoreServer";
public static final String RANK_NORMALIZATION = "FullTextSearchRankNormalization";
private List<String> propertyList = new ArrayList<String>(
Arrays.asList(ALLOW_UNPAGED_DS_MANUAL_REQUEST, ALLOW_UNSECURED_DS_REQUEST,
ALLOW_WHERE_PARAMETER, RESTRICT_ERP_ACCESS_IN_STORE_SERVER));
ALLOW_WHERE_PARAMETER, RESTRICT_ERP_ACCESS_IN_STORE_SERVER, RANK_NORMALIZATION));
private transient Map<String, String> cachedPreference;
/**
......
......@@ -11,7 +11,7 @@
* under the License.
* The Original Code is Openbravo ERP.
* The Initial Developer of the Original Code is Openbravo SLU
* All portions are Copyright (C) 2018 Openbravo SLU
* All portions are Copyright (C) 2018-2020 Openbravo SLU
* All Rights Reserved.
* Contributor(s): ______________________________________.
************************************************************************
......@@ -50,6 +50,8 @@ public class KernelSQLFunctionRegister implements SQLFunctionRegister {
sqlFunctions.put("now", new NoArgSQLFunction("now", StandardBasicTypes.TIMESTAMP));
sqlFunctions.put("to_timestamp",
new StandardSQLFunction("to_timestamp", StandardBasicTypes.TIMESTAMP));
sqlFunctions.put("fullTextSearchFilter", new PgFullTextSearchFunction.Filter());
sqlFunctions.put("fullTextSearchRank", new PgFullTextSearchFunction.Rank());
return sqlFunctions;
}
}
/*
*************************************************************************
* The contents of this file are subject to the Openbravo Public License
* Version 1.1 (the "License"), being the Mozilla Public License
* Version 1.1 with a permitted attribution clause; you may not use this
* file except in compliance with the License. You may obtain a copy of
* the License at http://www.openbravo.com/legal/license.html
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
* The Original Code is Openbravo ERP.
* The Initial Developer of the Original Code is Openbravo SLU
* All portions are Copyright (C) 2020 Openbravo SLU
* All Rights Reserved.
* Contributor(s): ______________________________________.
************************************************************************
*/
package org.openbravo.client.kernel;
import java.util.List;
import java.util.Optional;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.engine.spi.Mapping;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.type.BigDecimalType;
import org.hibernate.type.BooleanType;
import org.hibernate.type.Type;
import org.openbravo.base.exception.OBException;
import org.openbravo.client.application.CachedPreference;
/**
* HQL functions to support Full Text Search in PostgreSQL. See each class for more specific
* documentation
*/
public abstract class PgFullTextSearchFunction implements SQLFunction {
protected abstract String getFragment(String table, String field, String value,
Optional<String> ftsConfiguration);
@Override
public boolean hasArguments() {
return true;
}
@Override
public boolean hasParenthesesIfNoArguments() {
return false;
}
/**
* Function that parses the HQL function to SQL language:
*
* @param args
* list of arguments passed to fullTextSearchFilter hbm function
* <ul>
* <li>table
* <li>field: tsvector column of table
* <li>ftsconfiguration [optional]: language to pass to to_tsquery function
* <li>value: string to be searched/compared
* </ul>
* @return hql string to append to an hql query in order to filter/obtain the rank. See examples
* for each class in each class' doc
*/
@Override
public String render(Type type, @SuppressWarnings("rawtypes") List args,
SessionFactoryImplementor factory) {
if (args == null || args.size() < 3) {
throw new IllegalArgumentException("The function must be passed at least 3 arguments");
}
int pointPosition = args.get(0).toString().indexOf(".");
String table = args.get(0).toString().substring(0, pointPosition);
String field = (String) args.get(1);
Optional<String> ftsConfiguration = Optional
.ofNullable(args.size() == 4 ? (String) args.get(2) : null);
String value = (String) args.get(args.size() == 4 ? 3 : 2);
return getFragment(table, field, value, ftsConfiguration);
}
protected String getFtsConfig(Optional<String> ftsConfiguration) {
return ftsConfiguration.map(config -> config + "::regconfig, ").orElseGet(() -> "");
}
/**
* It allows to add a where clause to filter by those values that fit the search. In order for
* this to work there needs to be a column stored in the database that contains a tsvector built
* with the columns for which the search is required.
* <p>
* Examples of usage having p as alias of a product table and searchable_field as the tsvector
* field:
* <p>
* - 'and fullTextSearchFilter(p, p.searchable_field, 'english', 'cat')' this will search for any
* field that has any word having to do with cat
* <p>
* - 'and fullTextSearchFilter(p, p.searchable_field, 'english', 'cat:* | black:*')' this will
* search for any field that has any word having to do with cat or black and that starts at least
* by cat or black
*
*/
public static class Filter extends PgFullTextSearchFunction {
@Override
public Type getReturnType(Type arg0, Mapping arg1) {
return new BooleanType();
}
@Override
protected String getFragment(String table, String field, String value,
Optional<String> ftsConfiguration) {
return table + "." + field + " @@ to_tsquery(" + getFtsConfig(ftsConfiguration) + value + ")";
}
}
/**
* It allows to add an order by clause regarding how fitting a text is according to the values in
* the tsvector column. This function returns an integer that can be returned in the select clause
* and order by it. It is strictly not necessary to put it in the select clause, but it helps to
* know how it orders.
* <p>
* Examples of usage having p as alias of a product table and searchable_field as the tsvector
* field:
* <p>
* - 'fullTextSearchRank(p, p.searchable_field, 'english', 'cat')' this will return an integer
* that will be higher the more fitting to it the chain with which the tsvector field was and the
* more times the cat chain appeared on it
* <p>
* - 'fullTextSearchRank(p, p.searchable_field, 'english', 'cat:* | black:*')' same as before but
* with substrings and with cat or black
*
*/
public static class Rank extends PgFullTextSearchFunction {
@Override
public Type getReturnType(Type arg0, Mapping arg1) {
return new BigDecimalType();
}
/**
* Gets rank normalization from a preference, it needs to be an integer. According to Postgresql
* documentation {@link "https://www.postgresql.org/docs/current/textsearch-controls.html"}
* <p>
* Since a longer document has a greater chance of containing a query term it is reasonable to
* take into account document size, e.g., a hundred-word document with five instances of a
* search word is probably more relevant than a thousand-word document with five instances. Both
* ranking functions take an integer normalization option that specifies whether and how a
* document's length should impact its rank. The integer option controls several behaviors, so
* it is a bit mask: you can specify one or more behaviors using | (for example, 2|4).
* <p>
* <ul>
* <li>0 (the default) ignores the document length
* <li>1 divides the rank by 1 + the logarithm of the document length
* <li>2 divides the rank by the document length
* <li>4 divides the rank by the mean harmonic distance between extents (this is implemented
* only by ts_rank_cd)
* <li>8 divides the rank by the number of unique words in document
* <li>16 divides the rank by 1 + the logarithm of the number of unique words in document
* <li>32 divides the rank by itself + 1
* </ul>
* <p>
*
* @return numLike String
*/
protected String getRankNormalizationPref() {
CachedPreference cachedPreference = org.openbravo.base.weld.WeldUtils
.getInstanceFromStaticBeanManager(CachedPreference.class);
String rankNormalization = cachedPreference
.getPreferenceValue(CachedPreference.RANK_NORMALIZATION);
if (rankNormalization == null) {
return "0";
}
try {
Integer.parseInt(rankNormalization);
} catch (NumberFormatException nfe) {
throw new OBException("IncorrectFullTextSearchRankNormalization", nfe.getCause());
}
return rankNormalization;
}
@Override
protected String getFragment(String table, String field, String value,
Optional<String> ftsConfiguration) {
return "ts_rank_cd(" + table + "." + field + ", to_tsquery(" + getFtsConfig(ftsConfiguration)
+ value + "), " + getRankNormalizationPref() + ")";
}
}
}
......@@ -22,7 +22,7 @@
* parts created by ComPiere are Copyright (C) ComPiere, Inc.;
* All Rights Reserved.
* Contributor(s): Openbravo SLU
* Contributions are Copyright (C) 2001-2019 Openbravo, S.L.U.
* Contributions are Copyright (C) 2001-2020 Openbravo, S.L.U.
*
* Specifically, this derivative work is based upon the following Compiere
* file and version.
......@@ -213,6 +213,9 @@
v_AD_Reference_ID:='23';
ELSIF(Cur_Column.Data_Type IN ('TEXT', 'CLOB')) THEN
v_AD_Reference_ID:='14';
ELSIF(Cur_Column.Data_Type IN ('TSVECTOR')) THEN
v_AD_Reference_ID:='81FCDA657A5540F69B0AE57B4E0F8A51';
v_FieldLength:=0;
ELSE
v_AD_Reference_ID:='10'; -- if not found, use String
v_CorrectType:='N';
......
......@@ -22,7 +22,7 @@
* parts created by ComPiere are Copyright (C) ComPiere, Inc.;
* All Rights Reserved.
* Contributor(s): Openbravo SLU
* Contributions are Copyright (C) 2001-2012 Openbravo, S.L.U.
* Contributions are Copyright (C) 2001-2020 Openbravo, S.L.U.
*
* Specifically, this derivative work is based upon the following Compiere
* file and version.
......@@ -124,14 +124,16 @@
FOR Cur_Column IN(-- added by Pablo Sarobe
SELECT c.Columnname, c.Name, c.Description, c.Help, c.AD_Column_ID, c.FieldLength, t.tablename, c.AD_Module_ID, c.IsIdentifier, c.sqllogic
FROM AD_Column c, AD_Table t
FROM AD_Column c, AD_Table t, user_tab_columns utc
WHERE NOT EXISTS
(SELECT *
FROM AD_Field f
WHERE c.AD_Column_ID=f.AD_Column_ID AND c.AD_Table_ID=v_AD_Table_ID AND f.AD_Tab_ID=v_Record_ID
)
AND c.AD_Table_ID=v_AD_Table_ID AND c.AD_Table_ID=t.AD_Table_ID -- added by Pablo Sarobe
AND utc.table_name = t.tablename AND utc.column_name = c.Columnname
AND UPPER(c.Columnname) NOT IN ('CREATED', 'UPDATED', 'CREATEDBY', 'UPDATEDBY') AND c.IsActive='Y'
AND utc.data_type <> 'TSVECTOR'
ORDER BY POSITION)
LOOP
v_showInRelation:='N';
......
......@@ -2,7 +2,6 @@
<database name="TRIGGER AD_FIELD_MOD_TRG">
<trigger name="AD_FIELD_MOD_TRG" table="AD_FIELD" fires="before" insert="true" update="true" delete="true" foreach="row">
<body><![CDATA[
/*************************************************************************
* The contents of this file are subject to the Openbravo Public License
* Version 1.1 (the "License"), being the Mozilla Public License
......@@ -15,7 +14,7 @@
* under the License.
* The Original Code is Openbravo ERP.
* The Initial Developer of the Original Code is Openbravo SLU
* All portions are Copyright (C) 2008-2012 Openbravo SLU
* All portions are Copyright (C) 2008-2020 Openbravo SLU
* All Rights Reserved.
* Contributor(s): ______________________________________.
************************************************************************/
......@@ -101,6 +100,20 @@ BEGIN
END IF;
END IF;
IF (UPDATING OR INSERTING) THEN
SELECT COUNT(*)
INTO vAux
FROM AD_COLUMN c, AD_TABLE t, USER_TAB_COLUMNS utc
WHERE c.AD_Table_ID = t.AD_Table_ID
AND UPPER(utc.Column_Name) = UPPER(c.ColumnName)
AND UPPER(utc.Table_Name) = UPPER(t.TableName)
AND c.AD_Column_ID = :NEW.AD_Column_ID
AND utc.Data_Type = 'TSVECTOR';
IF (vAux!=0) THEN
RAISE_APPLICATION_ERROR(-20000, '@TSV_NotAllowedInFields@');
END IF;
END IF;
IF ((DELETING OR INSERTING) AND devModule='N') THEN
RAISE_APPLICATION_ERROR(-20000, '@20533@');
END IF;
......
......@@ -18837,6 +18837,18 @@ Be aware that if the daily limit is exceeded @extraDays@ more times in the @numb
<!--3F020D25A0E64874B2C379215E2F383B--> <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
<!--3F020D25A0E64874B2C379215E2F383B--></AD_MESSAGE>
 
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--><AD_MESSAGE>
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--> <AD_MESSAGE_ID><![CDATA[3F616053E6C6475DBD5BE4A7C03DEA3A]]></AD_MESSAGE_ID>
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--> <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--> <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--> <ISACTIVE><![CDATA[Y]]></ISACTIVE>
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--> <VALUE><![CDATA[IncorrectFullTextSearchRankNormalization]]></VALUE>
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--> <MSGTEXT><![CDATA[The FullTextSearchRankNormalization preference is set to a value that is not an integer]]></MSGTEXT>
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--> <MSGTYPE><![CDATA[I]]></MSGTYPE>
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--> <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--> <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
<!--3F616053E6C6475DBD5BE4A7C03DEA3A--></AD_MESSAGE>
<!--3F6B20FBC89E4B758183842119CC290A--><AD_MESSAGE>
<!--3F6B20FBC89E4B758183842119CC290A--> <AD_MESSAGE_ID><![CDATA[3F6B20FBC89E4B758183842119CC290A]]></AD_MESSAGE_ID>
<!--3F6B20FBC89E4B758183842119CC290A--> <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
......@@ -22009,6 +22021,18 @@ You can upgrade the license of your instance by contacting Openbravo sales staff
<!--7E3E5C3B752A4026A78ADDFA826E4A1C--> <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
<!--7E3E5C3B752A4026A78ADDFA826E4A1C--></AD_MESSAGE>
 
<!--7EA86C24AF2E45909CA009FF3EE30EFF--><AD_MESSAGE>
<!--7EA86C24AF2E45909CA009FF3EE30EFF--> <AD_MESSAGE_ID><![CDATA[7EA86C24AF2E45909CA009FF3EE30EFF]]></AD_MESSAGE_ID>
<!--7EA86C24AF2E45909CA009FF3EE30EFF--> <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
<!--7EA86C24AF2E45909CA009FF3EE30EFF--> <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
<!--7EA86C24AF2E45909CA009FF3EE30EFF--> <ISACTIVE><![CDATA[Y]]></ISACTIVE>
<!--7EA86C24AF2E45909CA009FF3EE30EFF--> <VALUE><![CDATA[TSV_NotAllowedInFields]]></VALUE>
<!--7EA86C24AF2E45909CA009FF3EE30EFF--> <MSGTEXT><![CDATA[It is not allowed to create a Field linked to a Column of type TSVECTOR.]]></MSGTEXT>
<!--7EA86C24AF2E45909CA009FF3EE30EFF--> <MSGTYPE><![CDATA[E]]></MSGTYPE>
<!--7EA86C24AF2E45909CA009FF3EE30EFF--> <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
<!--7EA86C24AF2E45909CA009FF3EE30EFF--> <ISINCLUDEINI18N><![CDATA[N]]></ISINCLUDEINI18N>
<!--7EA86C24AF2E45909CA009FF3EE30EFF--></AD_MESSAGE>
<!--7F28FD8C7EDA46D2A2816407790740F9--><AD_MESSAGE>
<!--7F28FD8C7EDA46D2A2816407790740F9--> <AD_MESSAGE_ID><![CDATA[7F28FD8C7EDA46D2A2816407790740F9]]></AD_MESSAGE_ID>
<!--7F28FD8C7EDA46D2A2816407790740F9--> <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
......@@ -5871,6 +5871,19 @@ There is no any kind of timezone conversion. The stored date-time does not have
<!--80D920FE975340EDACC52885BA4C34D7--> <ISVALUEDISPLAYED><![CDATA[N]]></ISVALUEDISPLAYED>
<!--80D920FE975340EDACC52885BA4C34D7--></AD_REFERENCE>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--><AD_REFERENCE>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--> <AD_REFERENCE_ID><![CDATA[81FCDA657A5540F69B0AE57B4E0F8A51]]></AD_REFERENCE_ID>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--> <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--> <AD_ORG_ID><![CDATA[0]]></AD_ORG_ID>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--> <ISACTIVE><![CDATA[Y]]></ISACTIVE>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--> <NAME><![CDATA[Search Vector]]></NAME>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--> <AD_MODULE_ID><![CDATA[0]]></AD_MODULE_ID>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--> <ISBASEREFERENCE><![CDATA[Y]]></ISBASEREFERENCE>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--> <MODEL_IMPL><![CDATA[org.openbravo.base.model.domaintype.StringDomainType]]></MODEL_IMPL>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--> <UI_IMPL><![CDATA[org.openbravo.reference.ui.UISearchVector]]></UI_IMPL>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--> <ISVALUEDISPLAYED><![CDATA[N]]></ISVALUEDISPLAYED>
<!--81FCDA657A5540F69B0AE57B4E0F8A51--></AD_REFERENCE>
<!--8238E1DF040B4641877766194CD1EF33--><AD_REFERENCE>
<!--8238E1DF040B4641877766194CD1EF33--> <AD_REFERENCE_ID><![CDATA[8238E1DF040B4641877766194CD1EF33]]></AD_REFERENCE_ID>
<!--8238E1DF040B4641877766194CD1EF33--> <AD_CLIENT_ID><![CDATA[0]]></AD_CLIENT_ID>
......
<#assign SEARCH_VECTOR_REF_ID = "81FCDA657A5540F69B0AE57B4E0F8A51" >
<#function getter p>
<#if p.boolean>
<#return "is" + p.getterSetterName?cap_first>
......@@ -27,7 +28,7 @@
* under the License.
* The Original Code is Openbravo ERP.
* The Initial Developer of the Original Code is Openbravo SLU
* All portions are Copyright (C) 2008-2019 Openbravo SLU
* All portions are Copyright (C) 2008-2020 Openbravo SLU
* All Rights Reserved.
* Contributor(s): ______________________________________.
************************************************************************
......@@ -55,6 +56,7 @@ public class ${entity.simpleClassName} extends BaseOBObject ${entity.implementsS
<#list entity.properties as p>
<#if !p.computedColumn>
<#if !(p.domainType?? && p.domainType.reference?? && p.domainType.reference.id?matches(SEARCH_VECTOR_REF_ID))>
<#if p.allowDerivedRead() && !p.isBeingReferenced()>
/**
* Property ${p.name} stored <#if p.columnName??>in column ${p.columnName} </#if>in table ${entity.tableName} <@addSeeTag p/> * <@addDeprecationMessageIfNeeded property=p />
......@@ -69,6 +71,7 @@ public class ${entity.simpleClassName} extends BaseOBObject ${entity.implementsS
<@addDeprecationTagIfNeeded property=p />
public static final String PROPERTY_${p.name?upper_case} = "${p.name}";
</#if>
</#if>
</#list>
......@@ -107,6 +110,7 @@ public class ${entity.simpleClassName} extends BaseOBObject ${entity.implementsS
<#list entity.properties as p>
<#if !p.oneToMany>
<#if !(p.domainType?? && p.domainType.reference.id?matches(SEARCH_VECTOR_REF_ID))>
/**
* @see ${entity.simpleClassName}#<#if p.computedColumn>COMPUTED_COLUMN<#else>PROPERTY</#if>_${p.name?upper_case}
* <@addDeprecationMessageIfNeeded property=p />
......@@ -126,6 +130,8 @@ public class ${entity.simpleClassName} extends BaseOBObject ${entity.implementsS
</#if>
</#if>
}
</#if>
<#if !(p.domainType?? && p.domainType.reference.id?matches(SEARCH_VECTOR_REF_ID))>
/**
* @see ${entity.simpleClassName}#<#if p.computedColumn>COMPUTED_COLUMN<#else>PROPERTY</#if>_${p.name?upper_case}
* <@addDeprecationMessageIfNeeded property=p />
......@@ -145,6 +151,7 @@ public class ${entity.simpleClassName} extends BaseOBObject ${entity.implementsS
</#if>
</#if>
}
</#if>
</#if>
</#list>
......
......@@ -11,7 +11,7 @@
* under the License.
* The Original Code is Openbravo ERP.
* The Initial Developer of the Original Code is Openbravo SLU
* All portions are Copyright (C) 2008-2019 Openbravo SLU
* All portions are Copyright (C) 2008-2020 Openbravo SLU
* All Rights Reserved.
* Contributor(s): ______________________________________.
************************************************************************
......@@ -102,6 +102,7 @@ public class Entity {
private String treeType;
public static final String COMPUTED_COLUMNS_PROXY_PROPERTY = "_computedColumns";
public static final String COMPUTED_COLUMNS_CLASS_APPENDIX = "_ComputedColumns";
public static final String SEARCH_VECTOR_REF_ID = "81FCDA657A5540F69B0AE57B4E0F8A51";
public String getTreeType() {
return treeType;
......@@ -688,9 +689,12 @@ public class Entity {
*/
public List<Property> getRealProperties(boolean includeComputed) {
List<Property> result = new ArrayList<Property>();
boolean isPropertyTSVector;
for (Property p : properties) {
isPropertyTSVector = p.getDomainType() != null && p.getDomainType().getReference() != null
&& SEARCH_VECTOR_REF_ID.equals(p.getDomainType().getReference().getId());
if ((includeComputed || !p.isComputedColumn())
&& !Entity.COMPUTED_COLUMNS_PROXY_PROPERTY.equals(p.getName())) {
&& !Entity.COMPUTED_COLUMNS_PROXY_PROPERTY.equals(p.getName()) && !isPropertyTSVector) {
result.add(p);
}
}
......
......@@ -11,7 +11,7 @@
* under the License.
* The Original Code is Openbravo ERP.
* The Initial Developer of the Original Code is Openbravo SLU
* All portions are Copyright (C) 2008-2018 Openbravo SLU
* All portions are Copyright (C) 2008-2020 Openbravo SLU
* All Rights Reserved.
* Contributor(s): ______________________________________.
************************************************************************
......@@ -180,6 +180,11 @@ public class DalMappingGenerator implements OBSingleton {
continue;
}
if (p.getDomainType() != null && p.getDomainType().getReference() != null
&& Entity.SEARCH_VECTOR_REF_ID.equals(p.getDomainType().getReference().getId())) {
continue;
}
if (p.isOneToMany()) {
content.append(generateOneToMany(p));
} else {
......
/*
*************************************************************************
* The contents of this file are subject to the Openbravo Public License
* Version 1.1 (the "License"), being the Mozilla Public License
* Version 1.1 with a permitted attribution clause; you may not use this
* file except in compliance with the License. You may obtain a copy of
* the License at http://www.openbravo.com/legal/license.html
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
* The Original Code is Openbravo ERP.
* The Initial Developer of the Original Code is Openbravo SLU
* All portions are Copyright (C) 2020 Openbravo SLU
* All Rights Reserved.
* Contributor(s): ______________________________________.
************************************************************************
*/
package org.openbravo.reference.ui;
/**
* Reference class to be used in AD definition for a tsvector column based on the UIString class
*/
public class UISearchVector extends UITableDir {
public UISearchVector(String reference, String subreference) {
super(reference, subreference);
}
}
......@@ -11,7 +11,7 @@
* under the License.
* The Original Code is Openbravo ERP.
* The Initial Developer of the Original Code is Openbravo SLU
* All portions are Copyright (C) 2008-2019 Openbravo SLU
* All portions are Copyright (C) 2008-2020 Openbravo SLU
* All Rights Reserved.
* Contributor(s): ______________________________________.
************************************************************************
......@@ -448,7 +448,9 @@ public class DataSetService implements OBSingleton {
exportables = new ArrayList<Property>(entity.getProperties());
// now remove the excluded
for (final DataSetColumn dsc : dataSetColumns) {
if (dsc.isExcluded()) {
boolean isTSVector = dsc.getColumn().getReference() != null
&& Entity.SEARCH_VECTOR_REF_ID.equals(dsc.getColumn().getReference().getId());
if (dsc.isExcluded() || isTSVector) {
exportables.remove(entity.getPropertyByColumnName(dsc.getColumn().getDBColumnName()));
}
}
......@@ -457,7 +459,9 @@ public class DataSetService implements OBSingleton {
// and add the not excluded
exportables = new ArrayList<Property>();
for (final DataSetColumn dsc : dataSetColumns) {
if (!dsc.isExcluded()) {
boolean isTSVector = dsc.getColumn().getReference() != null
&& Entity.SEARCH_VECTOR_REF_ID.equals(dsc.getColumn().getReference().getId());
if (!dsc.isExcluded() && !isTSVector) {
exportables.add(entity.getPropertyByColumnName(dsc.getColumn().getDBColumnName()));
}
}
......
......@@ -11,7 +11,7 @@
* under the License.
* The Original Code is Openbravo ERP.
* The Initial Developer of the Original Code is Openbravo SLU
* All portions are Copyright (C) 2009-2019 Openbravo SLU
* All portions are Copyright (C) 2009-2020 Openbravo SLU
* All Rights Reserved.
* Contributor(s): ______________________________________.
************************************************************************
......@@ -596,7 +596,7 @@ public class DatabaseValidator implements SystemValidator {
final Class<?> prim = property.getPrimitiveObjectType();
if (prim == String.class || property.getDomainType() instanceof ButtonDomainType) {
checkType(dbColumn, dbTable, result,
new String[] { "VARCHAR", "NVARCHAR", "CHAR", "NCHAR", "CLOB" });
new String[] { "VARCHAR", "NVARCHAR", "CHAR", "NCHAR", "CLOB", "TSVECTOR" });
// there are too many differences which make this check not relevant/practical at the moment
// checkLength(dbColumn, dbTable, result, property.getFieldLength());
} else if (prim == Long.class) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment