Fix CriteriaBuidler#locate() arguments order rendering
This commit is contained in:
parent
370d9354fc
commit
b8fab567cc
|
@ -170,10 +170,10 @@ public class CacheDialect extends Dialect {
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
||||||
"$find(?1,?2)",
|
"$find(?2,?1)",
|
||||||
"$find(?1,?2,?3)",
|
"$find(?2,?1,?3)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER
|
||||||
).setArgumentListSignature("(string, pattern[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
CommonFunctionFactory.bitLength_pattern( queryEngine, "($length(?1)*8)" );
|
CommonFunctionFactory.bitLength_pattern( queryEngine, "($length(?1)*8)" );
|
||||||
|
|
||||||
useJdbcEscape(queryEngine, "sin");
|
useJdbcEscape(queryEngine, "sin");
|
||||||
|
|
|
@ -276,15 +276,15 @@ public class FirebirdDialect extends Dialect {
|
||||||
CommonFunctionFactory.reverse( queryEngine );
|
CommonFunctionFactory.reverse( queryEngine );
|
||||||
CommonFunctionFactory.bitandorxornot_binAndOrXorNot( queryEngine );
|
CommonFunctionFactory.bitandorxornot_binAndOrXorNot( queryEngine );
|
||||||
CommonFunctionFactory.leastGreatest_minMaxValue( queryEngine );
|
CommonFunctionFactory.leastGreatest_minMaxValue( queryEngine );
|
||||||
SqmFunctionRegistry functionRegistry = queryEngine.getSqmFunctionRegistry();
|
|
||||||
|
|
||||||
|
SqmFunctionRegistry functionRegistry = queryEngine.getSqmFunctionRegistry();
|
||||||
functionRegistry.registerBinaryTernaryPattern(
|
functionRegistry.registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
integerType,
|
integerType,
|
||||||
"position(?2 in ?1)",
|
"position(?1 in ?2)",
|
||||||
"position(?2,?1,?3)",
|
"position(?1,?2,?3)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER
|
||||||
).setArgumentListSignature( "(string, pattern[, start])" );
|
).setArgumentListSignature( "(pattern, string[, start])" );
|
||||||
functionRegistry.namedDescriptorBuilder( "ascii_val" )
|
functionRegistry.namedDescriptorBuilder( "ascii_val" )
|
||||||
.setExactArgumentCount( 1 )
|
.setExactArgumentCount( 1 )
|
||||||
.setInvariantType( shortType )
|
.setInvariantType( shortType )
|
||||||
|
|
|
@ -181,14 +181,7 @@ public class InformixDialect extends Dialect {
|
||||||
CommonFunctionFactory.monthsBetween( queryEngine );
|
CommonFunctionFactory.monthsBetween( queryEngine );
|
||||||
CommonFunctionFactory.stddev( queryEngine );
|
CommonFunctionFactory.stddev( queryEngine );
|
||||||
CommonFunctionFactory.variance( queryEngine );
|
CommonFunctionFactory.variance( queryEngine );
|
||||||
|
CommonFunctionFactory.locate_positionSubstring( queryEngine );
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
|
||||||
"locate",
|
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
|
||||||
"instr(?1,?2)",
|
|
||||||
"instr(?1,?2,?3)",
|
|
||||||
STRING, STRING, INTEGER
|
|
||||||
).setArgumentListSignature("(string, pattern[, start])");
|
|
||||||
|
|
||||||
//coalesce() and nullif() both supported since Informix 12
|
//coalesce() and nullif() both supported since Informix 12
|
||||||
|
|
||||||
|
|
|
@ -279,10 +279,16 @@ public class IngresDialect extends Dialect {
|
||||||
CommonFunctionFactory.format_dateFormat( queryEngine );
|
CommonFunctionFactory.format_dateFormat( queryEngine );
|
||||||
CommonFunctionFactory.dateTrunc( queryEngine );
|
CommonFunctionFactory.dateTrunc( queryEngine );
|
||||||
CommonFunctionFactory.bitLength_pattern( queryEngine, "octet_length(hex(?1))*4" );
|
CommonFunctionFactory.bitLength_pattern( queryEngine, "octet_length(hex(?1))*4" );
|
||||||
CommonFunctionFactory.locate_positionSubstring( queryEngine );
|
|
||||||
|
|
||||||
final BasicType<Integer> integerType = queryEngine.getTypeConfiguration().getBasicTypeRegistry()
|
final BasicType<Integer> integerType = queryEngine.getTypeConfiguration().getBasicTypeRegistry()
|
||||||
.resolve( StandardBasicTypes.INTEGER );
|
.resolve( StandardBasicTypes.INTEGER );
|
||||||
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
|
"locate",
|
||||||
|
integerType,
|
||||||
|
"position(?1 in ?2)",
|
||||||
|
"(position(?1 in substring(?2 from ?3))+(?3)-1)",
|
||||||
|
STRING, STRING, INTEGER
|
||||||
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().registerPattern( "extract", "date_part('?1',?2)", integerType );
|
queryEngine.getSqmFunctionRegistry().registerPattern( "extract", "date_part('?1',?2)", integerType );
|
||||||
|
|
||||||
|
|
|
@ -166,9 +166,9 @@ public class MaxDBDialect extends Dialect {
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
integerType, "index(?1,?2)", "index(?1,?2,?3)",
|
integerType, "index(?2,?1)", "index(?2,?1,?3)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER
|
||||||
).setArgumentListSignature("(string, pattern[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -274,10 +274,10 @@ public class SQLiteDialect extends Dialect {
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
integerType,
|
integerType,
|
||||||
"instr(?1,?2)",
|
"instr(?2,?1)",
|
||||||
"instr(?1,?2,?3)",
|
"instr(?2,?1,?3)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER
|
||||||
).setArgumentListSignature("(string, pattern[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"lpad",
|
"lpad",
|
||||||
stringType,
|
stringType,
|
||||||
|
|
|
@ -170,10 +170,10 @@ public class TimesTenDialect extends Dialect {
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
||||||
"instr(?1,?2)",
|
"instr(?2,?1)",
|
||||||
"instr(?1,?2,?3)",
|
"instr(?2,?1,?3)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER
|
||||||
).setArgumentListSignature("(string, pattern[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -277,10 +277,10 @@ public abstract class AbstractHANADialect extends Dialect {
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
||||||
"locate(?1,?2)",
|
"locate(?2,?1)",
|
||||||
"locate(?1,?2,?3)",
|
"locate(?2,?1,?3)",
|
||||||
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER
|
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER
|
||||||
).setArgumentListSignature("(string, pattern[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
|
|
||||||
CommonFunctionFactory.ceiling_ceil( queryEngine );
|
CommonFunctionFactory.ceiling_ceil( queryEngine );
|
||||||
CommonFunctionFactory.concat_pipeOperator( queryEngine );
|
CommonFunctionFactory.concat_pipeOperator( queryEngine );
|
||||||
|
|
|
@ -184,10 +184,10 @@ public class OracleDialect extends Dialect {
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
||||||
"instr(?1,?2)",
|
"instr(?2,?1)",
|
||||||
"instr(?1,?2,?3)",
|
"instr(?2,?1,?3)",
|
||||||
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER
|
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER
|
||||||
).setArgumentListSignature("(string, pattern[, start])");
|
).setArgumentListSignature("(pattern, string[, start])");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -449,13 +449,7 @@ public class PostgreSQLDialect extends Dialect {
|
||||||
CommonFunctionFactory.overlay( queryEngine );
|
CommonFunctionFactory.overlay( queryEngine );
|
||||||
CommonFunctionFactory.soundex( queryEngine ); //was introduced in Postgres 9 apparently
|
CommonFunctionFactory.soundex( queryEngine ); //was introduced in Postgres 9 apparently
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
CommonFunctionFactory.locate_positionSubstring( queryEngine );
|
||||||
"locate",
|
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
|
||||||
"position(?2 in ?1)",
|
|
||||||
"(position(?2 in substring(?1 from ?3))+(?3)-1)",
|
|
||||||
FunctionParameterType.STRING, FunctionParameterType.STRING, FunctionParameterType.INTEGER
|
|
||||||
).setArgumentListSignature("(string, pattern[, start])");
|
|
||||||
|
|
||||||
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
|
if ( getVersion().isSameOrAfter( 9, 4 ) ) {
|
||||||
CommonFunctionFactory.makeDateTimeTimestamp( queryEngine );
|
CommonFunctionFactory.makeDateTimeTimestamp( queryEngine );
|
||||||
|
|
|
@ -1548,40 +1548,29 @@ public class CommonFunctionFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void locate(QueryEngine queryEngine) {
|
public static void locate(QueryEngine queryEngine) {
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "locate" )
|
||||||
"locate",
|
.setInvariantType(
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER )
|
||||||
"locate(?2,?1)",
|
|
||||||
"locate(?2,?1,?3)",
|
|
||||||
STRING,
|
|
||||||
STRING,
|
|
||||||
INTEGER
|
|
||||||
)
|
)
|
||||||
.setArgumentListSignature( "(STRING string, STRING pattern[, INTEGER start])" );
|
.setArgumentCountBetween( 2, 3 )
|
||||||
|
.setParameterTypes(STRING, STRING, INTEGER)
|
||||||
|
.setArgumentListSignature( "(STRING pattern, STRING string[, INTEGER start])" )
|
||||||
|
.register();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transact SQL-style
|
* Transact SQL-style
|
||||||
*/
|
*/
|
||||||
public static void locate_charindex(QueryEngine queryEngine) {
|
public static void locate_charindex(QueryEngine queryEngine) {
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
|
||||||
"locate",
|
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
|
||||||
"charindex(?2,?1)",
|
|
||||||
"charindex(?2,?1,?3)",
|
|
||||||
STRING,
|
|
||||||
STRING,
|
|
||||||
INTEGER
|
|
||||||
).setArgumentListSignature( "(STRING string, STRING pattern[, INTEGER start])" );
|
|
||||||
|
|
||||||
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "charindex" )
|
queryEngine.getSqmFunctionRegistry().namedDescriptorBuilder( "charindex" )
|
||||||
.setInvariantType(
|
.setInvariantType(
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER )
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER )
|
||||||
)
|
)
|
||||||
.setArgumentCountBetween( 2, 3 )
|
.setArgumentCountBetween( 2, 3 )
|
||||||
.setParameterTypes( STRING, STRING, INTEGER )
|
.setParameterTypes(STRING, STRING, INTEGER)
|
||||||
.setArgumentListSignature( "(STRING pattern, STRING string[, INTEGER start])" )
|
.setArgumentListSignature( "(STRING pattern, STRING string[, INTEGER start])" )
|
||||||
.register();
|
.register();
|
||||||
|
queryEngine.getSqmFunctionRegistry().registerAlternateKey( "locate", "charindex" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1591,10 +1580,10 @@ public class CommonFunctionFactory {
|
||||||
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
queryEngine.getSqmFunctionRegistry().registerBinaryTernaryPattern(
|
||||||
"locate",
|
"locate",
|
||||||
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
queryEngine.getTypeConfiguration().getBasicTypeRegistry().resolve( StandardBasicTypes.INTEGER ),
|
||||||
"position(?2 in ?1)", "(position(?2 in substring(?1 from ?3))+?3)",
|
"position(?1 in ?2)", "(position(?1 in substring(?2 from ?3))+(?3)-1)",
|
||||||
STRING, STRING, INTEGER
|
STRING, STRING, INTEGER
|
||||||
)
|
)
|
||||||
.setArgumentListSignature( "(STRING string, STRING pattern[, INTEGER start])" );
|
.setArgumentListSignature( "(STRING pattern, STRING string[, INTEGER start])" );
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* ANSI-style substring
|
* ANSI-style substring
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.dialect.function;
|
package org.hibernate.dialect.function;
|
||||||
|
|
||||||
import org.hibernate.mapping.Collection;
|
|
||||||
import org.hibernate.query.ReturnableType;
|
import org.hibernate.query.ReturnableType;
|
||||||
import org.hibernate.query.spi.QueryEngine;
|
import org.hibernate.query.spi.QueryEngine;
|
||||||
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
import org.hibernate.query.sqm.function.AbstractSqmFunctionDescriptor;
|
||||||
|
@ -18,8 +17,6 @@ import org.hibernate.query.sqm.tree.SqmTypedNode;
|
||||||
import org.hibernate.type.StandardBasicTypes;
|
import org.hibernate.type.StandardBasicTypes;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
|
import static org.hibernate.query.sqm.produce.function.FunctionParameterType.STRING;
|
||||||
|
@ -45,18 +42,6 @@ public class LocatePositionEmulation extends AbstractSqmFunctionDescriptor {
|
||||||
ReturnableType<T> impliedResultType,
|
ReturnableType<T> impliedResultType,
|
||||||
QueryEngine queryEngine,
|
QueryEngine queryEngine,
|
||||||
TypeConfiguration typeConfiguration) {
|
TypeConfiguration typeConfiguration) {
|
||||||
if ( arguments instanceof ArrayList ) {
|
|
||||||
Collections.swap( arguments, 0, 1 );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
List<SqmTypedNode<?>> argumentTemp = new ArrayList<>( arguments.size() );
|
|
||||||
argumentTemp.add( arguments.get( 1 ) );
|
|
||||||
argumentTemp.add( arguments.get( 0 ) );
|
|
||||||
for ( int i = 2; i < arguments.size(); i++ ) {
|
|
||||||
argumentTemp.add( arguments.get( i ) );
|
|
||||||
}
|
|
||||||
arguments = argumentTemp;
|
|
||||||
}
|
|
||||||
return queryEngine.getSqmFunctionRegistry().findFunctionDescriptor( "locate" )
|
return queryEngine.getSqmFunctionRegistry().findFunctionDescriptor( "locate" )
|
||||||
.generateSqmExpression( arguments, impliedResultType, queryEngine, typeConfiguration );
|
.generateSqmExpression( arguments, impliedResultType, queryEngine, typeConfiguration );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1255,14 +1255,14 @@ public class SqmCriteriaNodeBuilder implements NodeBuilder, SqmCreationContext,
|
||||||
final List<SqmTypedNode<?>> arguments;
|
final List<SqmTypedNode<?>> arguments;
|
||||||
if ( startPosition == null ) {
|
if ( startPosition == null ) {
|
||||||
arguments = asList(
|
arguments = asList(
|
||||||
source,
|
pattern,
|
||||||
pattern
|
source
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
arguments = asList(
|
arguments = asList(
|
||||||
source,
|
|
||||||
pattern,
|
pattern,
|
||||||
|
source,
|
||||||
startPosition
|
startPosition
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,9 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
@Jpa(
|
@Jpa(
|
||||||
annotatedClasses = CriteriaLocateTest.Person.class
|
annotatedClasses = LocateTest.Person.class
|
||||||
)
|
)
|
||||||
public class CriteriaLocateTest {
|
public class LocateTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp(EntityManagerFactoryScope scope) {
|
public void setUp(EntityManagerFactoryScope scope) {
|
||||||
|
@ -112,6 +112,21 @@ public class CriteriaLocateTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void locateQueryTest(EntityManagerFactoryScope scope) {
|
||||||
|
scope.inTransaction(
|
||||||
|
entityManager -> {
|
||||||
|
final List<Integer> ids = entityManager.createQuery(
|
||||||
|
"select distinct p.id from Person p where locate('nd', p.name) = 2" )
|
||||||
|
.getResultList();
|
||||||
|
|
||||||
|
assertEquals( 2, ids.size() );
|
||||||
|
assertTrue( ids.contains( 3 ) );
|
||||||
|
assertTrue( ids.contains( 4 ) );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@Entity(name = "Person")
|
@Entity(name = "Person")
|
||||||
@Table(name = "PERSON_TABLE")
|
@Table(name = "PERSON_TABLE")
|
||||||
public static class Person {
|
public static class Person {
|
||||||
|
|
|
@ -407,11 +407,11 @@ public class FunctionTests {
|
||||||
public void testLocateFunction(SessionFactoryScope scope) {
|
public void testLocateFunction(SessionFactoryScope scope) {
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
session -> {
|
session -> {
|
||||||
session.createQuery("select locate( e.theString, 'hello') from EntityOfBasics e")
|
session.createQuery("select locate('hello', e.theString) from EntityOfBasics e")
|
||||||
.list();
|
.list();
|
||||||
session.createQuery("select locate( e.theString, 'hello', e.theInteger) from EntityOfBasics e")
|
session.createQuery("select locate('hello', e.theString, e.theInteger) from EntityOfBasics e")
|
||||||
.list();
|
.list();
|
||||||
assertThat( session.createQuery("select locate( 'hello world', 'world')").getSingleResult(), is(7) );
|
assertThat( session.createQuery("select locate('world', 'hello world')").getSingleResult(), is(7) );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue