Skip to content

Commit

Permalink
manifold-sql changes
Browse files Browse the repository at this point in the history
- settled on Entity as the most apt term for schema interfaces and classes, rename refactor accordingly
- interface/class extension support
-- custom instance creation support via CustomEntityFactory dependency
-- custom entity interface support via naming convention e.g.,  public interface CustomStore extends CustomEntity<Store> {...}
-- custom base interface support via dbconfig
-- custom base class support via dbconfig
  • Loading branch information
rsmckinney committed Oct 30, 2023
1 parent bbe9426 commit 14ecebe
Show file tree
Hide file tree
Showing 31 changed files with 575 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package manifold.rt.api;

import manifold.rt.api.util.ManObjectUtil;

import java.util.Map;

/**
Expand All @@ -27,4 +29,42 @@ public interface Bindings extends Map<String, Object>
* Supports maintaining metadata about this instance
*/
Bindings getMetadata();

default String displayEntries()
{
StringBuilder row = new StringBuilder();
for( Map.Entry<String, Object> entry : entrySet() )
{
if( row.length() > 0 )
{
row.append( ", " );
}
row.append( entry.getKey() ).append( ": " );
Object value = entry.getValue();
if( value instanceof String )
{
value = "\"" + value + "\"";
}
row.append( ManObjectUtil.toString( value ) );
}
return row.toString();
}

default String displayValues()
{
StringBuilder row = new StringBuilder();
for( Object value : values() )
{
if( row.length() > 0 )
{
row.append( ", " );
}
if( value instanceof String )
{
value = "\"" + value + "\"";
}
row.append( ManObjectUtil.toString( value ) );
}
return row.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,28 @@ else if( !Character.isJavaIdentifierStart( part.charAt( 0 ) ) )
}
}

public static boolean isValidClassName( String name )
{
while( name.length() != 0 )
{
int iDot = name.indexOf( '.' );
if( iDot < 0 )
{
iDot = name.length();
}
if( !isJavaIdentifier( name.substring( 0, iDot ) ) )
{
return false;
}
name = name.substring( iDot );
if( name.length() != 0 )
{
name = name.substring( 1 );
}
}
return true;
}

public static Class<?> box( Class<?> type )
{
if( type == boolean.class )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package manifold.rt.api.util;

import java.io.Serializable;
import java.util.Arrays;

/**
* <p>This class is directly derived from org.apache.commons.lang.ObjectUtils and is
Expand Down Expand Up @@ -254,7 +255,7 @@ public static StringBuffer appendIdentityToString( StringBuffer buffer, Object o
*/
public static String toString( Object obj )
{
return obj == null ? "" : obj.toString();
return toString( obj, "null" );
}

/**
Expand All @@ -279,7 +280,50 @@ public static String toString( Object obj )
*/
public static String toString( Object obj, String nullStr )
{
return obj == null ? nullStr : obj.toString();
return obj == null
? nullStr
: obj.getClass().isArray()
? arrayToString( obj )
: obj.toString();
}

public static String arrayToString( Object array )
{
if( array == null )
{
return "null";
}

Class<?> componentType = array.getClass().getComponentType();
if( componentType.isPrimitive() )
{
switch( componentType.getTypeName() )
{
case "byte":
return Arrays.toString( (byte[])array );
case "short":
return Arrays.toString( (short[])array );
case "int":
return Arrays.toString( (int[])array );
case "long":
return Arrays.toString( (long[])array );
case "float":
return Arrays.toString( (float[])array );
case "double":
return Arrays.toString( (double[])array );
case "char":
return Arrays.toString( (char[])array );
case "boolean":
return Arrays.toString( (boolean[])array );
default:
throw new IllegalStateException();
}
}
else if( !componentType.isArray() )
{
return Arrays.toString( (Object[])array );
}
return Arrays.deepToString( (Object[])array );
}

// Min/Max
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3433,7 +3433,7 @@ public static String join( Iterator iterator, char separator )
Object first = iterator.next();
if( !iterator.hasNext() )
{
return ManObjectUtil.toString( first );
return ManObjectUtil.toString( first, "" );
}

// two or more elements
Expand Down Expand Up @@ -3485,7 +3485,7 @@ public static String join( Iterator iterator, String separator )
Object first = iterator.next();
if( !iterator.hasNext() )
{
return ManObjectUtil.toString( first );
return ManObjectUtil.toString( first, "" );
}

// two or more elements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public static <E> boolean addAll( @This Collection<E> thiz, Iterable<? extends E

public static <E> String join( @This Collection<E> thiz, CharSequence delimiter )
{
return thiz.stream().map( ManObjectUtil::toString ).collect( Collectors.joining( delimiter ) );
return thiz.stream().map( obj -> ManObjectUtil.toString( obj, "" ) ).collect( Collectors.joining( delimiter ) );
}

public static <E> List<E> toList( @This Collection<E> thiz )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,6 @@ public interface IBindingsBacked

default String display()
{
StringBuilder row = new StringBuilder();
for( Object value: getBindings().values() )
{
if( row.length() > 0 )
{
row.append( ", " );
}
if( value instanceof String )
{
value = "\"" + value + "\"";
}
row.append( value );
}
return row.toString();
return getBindings().displayEntries();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2023 - Manifold Systems LLC
*
* 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 manifold.sql.schema.customize;

import manifold.ext.rt.api.auto;
import manifold.sql.schema.simple.h2.H2Sakila.*;
import manifold.sql.schema.h2.base.H2DdlServerTest;
import org.junit.Test;

import java.io.IOException;

import static org.junit.Assert.assertEquals;

public class CustomInterfaceTest extends H2DdlServerTest
{
@Test
public void testCustomInterface() throws IOException
{
loadData( "/samples/data/h2-sakila-data.sql" );

auto query = "[.sql:H2Sakila/] Select * From store where store_id = :store_id";
Store store = query.fetchOne( 1L );
assertEquals( 1L, store.myCustomMethod() ); // from neighboring CustomStore
assertEquals( "myCustomBaseMethod", store.myCustomBaseMethod() ); // from dbconfig "customBaseClass"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2023 - Manifold Systems LLC
*
* 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 manifold.sql.schema.customize;

import manifold.sql.rt.api.CustomEntity;
import manifold.sql.schema.simple.h2.H2Sakila.Store;

/**
* Following the "Custom" + [entity interface name] naming convention, this interface becomes a super interface for Store.
* As such, methods defined here are accessible directly from instances of Store.
*/
public interface CustomStore extends CustomEntity<Store>
{
default long myCustomMethod()
{
return self().getStoreId();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2023 - Manifold Systems LLC
*
* 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 manifold.sql.schema.customize;

import manifold.sql.rt.api.BaseEntity;
import manifold.sql.rt.api.TxBindings;

public abstract class MyBaseClass extends BaseEntity implements MyBaseInterface
{
public MyBaseClass( TxBindings txBindings )
{
super( txBindings );
}

public String myCustomBaseMethod()
{
return "myCustomBaseMethod";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@
* limitations under the License.
*/

package manifold.sql.rt.api;
package manifold.sql.schema.customize;

/**
* Common base type for db table types (generated from the schema).
*/
public interface TableRow extends ResultRow
public interface MyBaseInterface
{
TableInfo tableInfo();
String myCustomBaseMethod();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
"url": "jdbc:h2:mem:h2_sakila",
"schemaPackage": "manifold.sql.schema.simple.h2",
"dbDdl": "/samples/ddl/h2-sakila-ddl.sql",
"inMemory": true
"inMemory": true,
"customBaseInterface": "manifold.sql.schema.customize.MyBaseInterface",
"customBaseClass": "manifold.sql.schema.customize.MyBaseClass"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 - Manifold Systems LLC
*
* 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 manifold.sql.rt.api;

/**
* Generated "Entity" classes from SchemaParentType extend this base class. Custom classes via {@link CustomEntityFactory}
* must subclass this as well, or if a different super class is needed, the subclass must duplicate the behavior here.
*/
public abstract class BaseEntity implements ResultRow
{
private final TxBindings _txBindings;

public BaseEntity( TxBindings txBindings )
{
_txBindings = txBindings;
}

@Override
public TxBindings getBindings()
{
return _txBindings;
}

public String toString()
{
return "{" + getBindings().displayEntries() + "}";
}

@Override
public int hashCode()
{
return getBindings().hashCode();
}

@Override
public boolean equals( Object o )
{
if( this == o )
{
return true;
}
if( o == null || getClass() != o.getClass() )
{
return false;
}
BaseEntity that = (BaseEntity)o;
return getBindings().equals( that.getBindings() );
}
}
Loading

0 comments on commit 14ecebe

Please sign in to comment.