Subsonic Simplerepository GetPaged<T> Enum issues - subsonic3

At one point, SimpleRepository didn't support enums. If you had a POCO object with an Enum it wouldn't persist correctly, you had to have a backing variable which you would use eg:
public enum Color
{
Red = 1,
Blue = 2
}
public class Car
{
[SubSonicIgnore]
public Color CarColor
{
get
{
return (Color)ColorMe;
}
set
{
ColorMe= (int)value;
}
}
public int ColorMe;
}
The name in your table would then have to be the named of the variable, and not the enum.
This issue was resolved with a recent patch on github.
However, I'm still seeing issues when trying to use GetPaged
var results = Db.GetPaged<Car>(1, 10);
Throws an exception:
**Tests.Models.NewTests.SimplePagedSearch threw exception: System.InvalidCastException: Invalid cast from 'System.Int32' to 'Models.Car.Color**
This exception occurs at line 95 of
SubSonic.Extensions.Objects.ChangeTypeTo(Object value, Type conversionType) in C:\TEMP\subsonic\SubSonic.Core\Extensions\Objects.cs: line 95

I patched Subsonic.Extensions.Objects.ChangeTypeTo line 95 to include this clause:
else if (conversionType.IsEnum)
{
return Enum.ToObject(conversionType, value);
}
So a direct cast from int32 to Enum no longer throws and exception

Related

Ballerina range expression implemenation problem with Iterator object. Incompatible types error

I'm trying to understand the way this example code works in the Range Expressions Example on Ballerina By Example. I'm using Ballerina 1.0.5.
I'm facing an issue at the line } iterableObj = 25 ..< 28; where I get an incompatible types error. I've tried to replicate the type that it needs by trying various things including switching between exclusive and inclusive record descriptors but I can't seem to be able to figure it out. I'm also new to this language.
When I run the code below. It gives me the error as follows:
Error
error: .::range_expressions.bal:20:21: incompatible types: expected 'object { public function __iterator () returns (object { public function next () returns (record {| int value; |}?); }); }', found 'object { public function next () returns (record {| int value; |}?); }'
Code
import ballerina/io;
public function main() {
io:println("foreach for 25 ... 28");
foreach int i in 25 ... 28 {
io:println(i);
}
io:println("\nforeach for 25 ..< 28");
foreach int i in 25 ..< 28 {
io:println(i);
}
abstract object {
public function __iterator() returns
abstract object {
public function next() returns record {|int value;|}?;
};
} iterableObj = 25 ..< 28; // facing an issue here
abstract object {
public function next() returns (record {|int value;|}?);
} iterator = iterableObj.__iterator();
io:println("\niterable object for 25 ..< 28");
while (true) {
record {| int value; |}? r = iterator.next();
if (r is record {| int value; |}) {
io:println(r.value);
} else {
break;
}
}
}
Misc. Info
I'm having a similar issue with the example Iterable Objects. I get an incompatible types error when I try to execute the code in that example as well and I think the underlying problem is the implementation of iterator objects. I don't think I should post the code here or the question will seem far too long.
Per the info:
Any subtype of abstract object {public next() returns record {| T value; |}?;}, is called Iterator.
Main Question
I've gone through what I can glean from the language specifications and I can't seem to figure this out. Could you please tell me how to fix this error and if possible, a small explanation of the way the example works?
I think the issue is that the code you are trying to implement is a new addition in 1.1.0 release, 1.1.0 was release on 19/12/2019.
You can either download the 1.1.0 or use the version selector in the web site to get pre 1.1.0 documentation. There should be a version selector in top right of the webpage, from there you can select 1.0 to get the documentation for 1.0.5 compiler.
Edit:
There seems to be a bug in the website that prevent you from accessing versioned Ballerina by examples. Please use the source code of them for now. https://github.com/ballerina-platform/ballerina-lang/tree/release-1.0.5/examples

Compiler pass - resolve target entity doesn't load

I'm working on a bundle and i need to load a doctrine resolve_target_entities from a configuration parameter.
This article should be my solution, the fact is that using the bundle it seems not to load the "compiler pass class".
This is my bundle class
class PersonalBundle extends Bundle
{
public function build(ContainerBuilder $container){
parent::build($container);
$container->addCompilerPass(new ResolveTargetEntitiesPass());
}
}
This is the ResolveTargetEntitiesPass class
class ResolveTargetEntitiesPass implements CompilerPassInterface
{
/**
* {#inheritdoc}
*/
public function process(ContainerBuilder $container)
{
// Gets the custom entity defined by the user (or the default one)
$customEntityClass = $container->getParameter('personal.custom_class');
// Skip the resolve_target_entities part if user has not defined a different entity
if (DefaultClassInterface::DEFAULT_ENTITY_CLASS == $customEntityClass) {
return;
}
// Throws exception if the class isn't found
if (!class_exists($customEntityClass)) {
throw new ClassNotFoundException(sprintf("Can't find class %s ", $customEntityClass));
}
// Get the doctrine ResolveTargetEntityListener
$def = $container->findDefinition('doctrine.orm.listeners.resolve_target_entity');
// Adds the resolve_target_enitity parameter
$def->addMethodCall('addResolveTargetEntity', array(
DefaultClassInterface::DEFAULT_ENTITY_CLASS, $customEntityClass, array()
));
// This was added due this problem
// https://stackoverflow.com/a/46656413/7070573
if (version_compare(Version::VERSION, '2.5.0-DEV') < 0 && !$def->hasTag('doctrine.event_listener')) {
$def->addTag('doctrine.event_listener', array('event' => 'loadClassMetadata'));
} elseif (!$def->hasTag('doctrine.event_subscriber')) {
$def->addTag('doctrine.event_subscriber');
}
}
}
When i use the class it raises this error
Expected value of type "PersonalBundle\Entity\DefaultClass"
for association field "PersonalBundle\Entity\Group#$defaultClass", got
"App\Entity\CustomClass" instead.
As i said it seems not to load the ResolveTargetEntitiesPass...
Thanks
So i solved the problem changing the priority of the compiler pass.
I've tried to move the bundle on top in config/bundle.php and it started working, then following this https://symfony.com/blog/new-in-symfony-3-2-compiler-passes-improvements i've left the default type but increased the priority (from 0, default, to 1).
I'm not sure which service has been "downgraded" so if anyone has an idea it's welcome.
<?php
// ...
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
class PersonalBundle extends Bundle
{
public function build(ContainerBuilder $container){
parent::build($container);
$container->addCompilerPass(new ResolveTargetEntitiesPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 1);
}
}

Unable to check exception type in google test

I'm unable to check the exception throw by my code in gtests. Here's a snippet of the test suite which runs the test:
EXPECT_THROW({
try{
// Insert a tuple with more target columns than values
rows_changed = 0;
query = "INSERT INTO test8(num1, num3) VALUES(3);";
txn = txn_manager.BeginTransaction();
plan = TestingSQLUtil::GeneratePlanWithOptimizer(optimizer, query, txn);
EXPECT_EQ(plan->GetPlanNodeType(), PlanNodeType::INSERT);
txn_manager.CommitTransaction(txn);
TestingSQLUtil::ExecuteSQLQueryWithOptimizer(
optimizer, query, result, tuple_descriptor, rows_changed, error_message);
}
catch (CatalogException &ex){
EXPECT_STREQ("ERROR: INSERT has more target columns than expressions", ex.what());
}
}, CatalogException);
I'm pretty sure that CatalogException is thrown. I even tried getting the details of the thrown exception by outputting it to cerr, and it showed Exception Type: Catalog.
This is not a duplicate question, I searched for answers on SO and I'm not using new in my code which throws the error. Here's the snippet which does that:
if (columns->size() < tup_size)
throw CatalogException(
"ERROR: INSERT has more expressions than target columns");
Finally, here's the definition of CatalogException:
class CatalogException : public Exception {
CatalogException() = delete;
public:
CatalogException(std::string msg) : Exception(ExceptionType::CATALOG, msg) {}
};
The idea from EXPECT_THROW is, that the macro catches the exception. If you catch the exception by yourself, gmock don't now anything about a thrown exception.
I suggest to just write the statement into the EXPECT_THROW, which actually trigger the exception. Everything else can be written before.
For example:
TEST(testcase, testname)
{
//arrange everything:
//...
//act + assert:
EXPECT_THROW(TestingSQLUtil::ExecuteSQLQueryWithOptimizer( optimizer, query, result,
tuple_descriptor, rows_changed, error_message)
,CatalogException);
}
I assume, that TestingSQLUtil::ExecuteSQLQueryWithOptimizer is trigger the thrown exception.
addition:
I tried to rebuild your exception hierarchy. This example works for me very well. The test passes, which means the exception is thrown.
enum class ExceptionType
{
CATALOG
};
class Exception {
public:
Exception(ExceptionType type, std::string msg) {}
};
class CatalogException : public Exception {
CatalogException() = delete;
public:
CatalogException(std::string msg) : Exception(ExceptionType::CATALOG, msg) {}
};
void testThrow() {
throw CatalogException( "ERROR: INSERT has more expressions than target columns");
}
TEST(a,b) {
EXPECT_THROW( testThrow(), CatalogException);
}

Recommended Access Modifiers for Testability of Wrapper Methods

One thing I have started doing in my tests is to wrap error messages and string concatenations into methods or variables to keep my tests robust should the error message contents change later.
So for example, I would refactor something like this:
try{
someMethod();
}catch(e){
throw new Error('error message.');
}
into this:
let errorMessage = 'error message';
...
try{
someMethod();
}catch(e){
throw new Error(errorMessage);
}
Or something similar if the error message contains a variable or something.
My question is what would be the best way to do this in Typescript? In Java I would have them be package-protected, but here it seems Jasmine does not have access to methods like this if they are protected. I have also tried making them static.
Is there preferred method for this?
This is one occasion where you can transfer some good practices from other languages.
If you create custom exceptions, you can test their type, rather than the strings - and you can also ensure uniformity of error messages.
This example looks a bit convoluted, but it should give you an idea (adapted from page 163-168 Pro Typescript).
A base CustomException class is created that implements the Error interface and will sit beneath any custom error types we want in our application.
An InvalidDateException is created to represent a particular class of error, this is the only place the error message string needs to be stored in the application.
You can now look at particular kinds of error as in the example catch statement where instanceof is used to check the type.
All your custom exceptions are compatible with the Error interface, which required name and toString().
Code:
class CustomException implements Error {
protected name = 'CustomException';
constructor(public message: string) {
}
toString() {
return this.name + ': ' + this.message;
}
}
class InvalidDateException extends CustomException {
constructor(public date: Date) {
super('The date supplied was not valid: ' + date.toISOString());
this.name = 'InvalidDateException';
}
}
try {
throw new InvalidDateException(new Date());
} catch (ex) {
if (ex instanceof InvalidDateException) {
alert(ex.toString());
}
}

MVC 4 - String Custom Template messing with Enums

I have a custom template ~/Views/Shared/EditorTemplate/String.cshtml and it seems to be causing the Exception:
The model item passed into the dictionary is of type 'Proj.Models.EnumType', but this dictionary requires a model item of type 'System.String'.
It seems to only happen to Enums. It also goes away if I remove the template. The template doesn't seem to cause it, I don't think it's even making it that far. I can put ANYTHING in there and the exception is the same.
So... can I not use an #Html.EditorFor with a model with an enum if I have a custom template?
Some context:
Model:
namespace Proj.Models
{
public enum EnumType
{
A = 0,
B = 1,
C = 2,
}
public class Mod
{
[Required]
public String Name;
[Required]
public EnumType Letter;
}
}
View:
#model Proj.Models.Mod
#Html.EditorFor(m=>m) // Exception happens here
Here is what I found to work for me.
In your template, make sure you declare your model as nullable enum type. Then, in code, check to see if it has a value and based on that do appropriate formatting.
#inherits System.Web.Mvc.WebViewPage<Proj.Models.EnumType?>
#{
Proj.Models.EnumType v = Model.HasValue ? Model.Value : {*some-default-value*};
#Html.{*Your-formatter-here*};
}