ServiceStack.OrmLite: StringLengthAttribute.MaxText produces "LONGTEXT" - how can I set to "TEXT"? - mysql

Using ServiceStack's OrmLite and decorating a Property with the following attribute, creates a column of type LONGTEXT, instead o TEXT as noted in the docs:
But it becomes LONGTEXT:
I tried setting the StringLenghtAttribute to something else, 65535, 70000, Int32.MaxValue etc, but it either interpretet it as a VARCHAR and gave me the Column length too big or Row size too large, or it became a LONGTEXT.
Question is: how can I force it to become "TEXT" (or any other text type in mysql)?
I could perhaps modify the MaxColumnDefinition and set it to TEXT but then I will never get LONGTEXT I assume.
Update
Setting the MaxColumnDefinition to TEXT didn't change a thing.
Can I decorate the class with an attribute, specifying the type somehow? Or is that too sql-version-specific?
Or perhaps I should override the GetColumnDefinition and implement my own logic...

(Please note that this solution produces other problems that I will ask in a separate SO post)
After some more research, it was solved creating my own StringConverter, as can be seen below:
public class MyStringConverter : StringConverter
{
public override string GetColumnDefinition(int? stringLength)
{
if (stringLength.GetValueOrDefault() == StringLengthAttribute.MaxText)
return MaxColumnDefinition;
if (stringLength.GetValueOrDefault(StringLength) <= 255)
{
return UseUnicode
? $"NVARCHAR({stringLength.GetValueOrDefault(StringLength)})"
: $"VARCHAR({stringLength.GetValueOrDefault(StringLength)})";
}
else if (stringLength.GetValueOrDefault(StringLength) <= 65535)
{
return $"TEXT";
}
else
{
return "LONGTEXT";
}
}
}
I also suggest setting the default StringLength to something smaller than the default 8000:
StringConverter converter = OrmLiteConfig.DialectProvider.GetStringConverter();
converter.StringLength = 255;
This way, the default string will be varchar(255). If you want to make a specific string property something else, then set the attribute according to the MyStringConverter:
type = typeof(tWorks.Core.CoreCommons.ContactModuleProtocols.SMS.ModuleSettingsSMS);
type.GetProperty(nameof(MyClass.Prop1)).AddAttributes(new StringLengthAttribute(255)); // ==> varchar(255)
type.GetProperty(nameof(MyClass.Prop2)).AddAttributes(new StringLengthAttribute(500)); // ==> TEXT
type.GetProperty(nameof(MyClass.Prop3)).AddAttributes(new StringLengthAttribute(70000)); // ==> LONGTEXT

Related

ServiceStack.OrmLite: Implementing custom StringConverter affects column type of complex BLOB fields

In a previous SO question I asked how I change the MySql column type when I have string properties in my POCOs.
The answer, which I answered myself, was to implement my own StringConverter. It was sort of an acceptable approach, I thought.
However, in my answer, I noted that not only was my string properties affected, so was all those properties that are complex and where OrmLite BLOBs them as JSON.
The field types for those complex columns in MySQL also became like varchar(255), which of course doesn't last very long.
The StringConverter was very short and easy:
I said that default string length is 255:
StringConverter converter = OrmLiteConfig.DialectProvider.GetStringConverter();
converter.StringLength = 255;
I wanted string props defined as 255 chars or smaller to be varchar(255)
string props defined as > 255 and < 65535 to be text
string props defined as >= 65535 to be longtext
MyStringConverter:
public class MyStringConverter : StringConverter
{
public override string GetColumnDefinition(int? stringLength)
{
if (stringLength.GetValueOrDefault() == StringLengthAttribute.MaxText)
return MaxColumnDefinition;
if (stringLength.GetValueOrDefault(StringLength) <= 255)
{
return UseUnicode
? $"NVARCHAR({stringLength.GetValueOrDefault(StringLength)})"
: $"VARCHAR({stringLength.GetValueOrDefault(StringLength)})";
}
else if (stringLength.GetValueOrDefault(StringLength) <= 65535)
{
return $"TEXT";
}
else
{
return "LONGTEXT";
}
}
}
But, as stated above, a property that looks like this (ActionInfo just contains some strings and List):
public List<ActionInfo> _AvailableActions { get; set; }
produced a table like this when using MyStringConverter:
Without using MyStringConverter, the column became a longtext.
Question is then: what am I missing? I still want complex, BLOBed fields to become longtext so that JSON BLOBing can be done. I was hoping that the StringConverter only affected string properties?
The column definition of blobbed complex types should use the ReferenceTypeConverter which by default resolves to DialectProvider.GetStringConverter().MaxColumnDefinition;
You should inherit the RDBMS-specific MySqlStringConverter if you want to change the string behavior of MySQL Strings otherwise you will revert back to inheriting generic RDBMS behavior which uses VARCHAR(8000) for strings and MaxColumnDefinition.
Alternatively you can override MaxColumnDefinition in your own String converter:
public override string MaxColumnDefinition => "LONGTEXT";

Can a logback message field be truncated/trimmed to n characters?

Sometimes see huge log messages and do not always have the ability to (easily) turn of word wrapping.
Is there a way to truncate %message to, say, 80 characters via logback.xml?
Have a look at the format modifiers section:
From http://logback.qos.ch/manual/layouts.html#formatModifiers:
Format modifiers
By default the relevant information is output as-is. However, with the aid of format modifiers it is possible to change the minimum and maximum width and the justifications of each data field.
...
Truncation from the end is possible by appending a minus character right after the period. In that case, if the maximum field width is eight and the data item is ten characters long, then the last two characters of the data item are dropped.
The Adrian's answer is great if you only need to truncate the message. However in my case I wanted to add "... [truncated]" in case of the really truncated messages.
I used a custom convertors mechanism for this purpose - by performing the following steps:
Define you custom converter:
public class LongMessagesConverter extends ClassicConverter {
private static final int MAX_FORMATTED_MESSAGE_LENGTH = 25600;
private static final String TRUNCATION_SUFFIX = "... [truncated]";
private static final int TRUNCATED_MESSAGE_SIZE =
TRUNCATION_SUFFIX.length() + MAX_FORMATTED_MESSAGE_LENGTH;
#Override
public String convert(ILoggingEvent event) {
String formattedMessage = event.getFormattedMessage();
if (formattedMessage == null ||
formattedMessage.length() < MAX_FORMATTED_MESSAGE_LENGTH) {
return formattedMessage;
}
return new StringBuilder(TRUNCATED_MESSAGE_SIZE)
.append(formattedMessage.substring(0, MAX_FORMATTED_MESSAGE_LENGTH))
.append(TRUNCATION_SUFFIX)
.toString();
}
}
Add to your logback.xml the following definition:
<conversionRule conversionWord="boundedMsg" converterClass="your.package.LongMessagesConverter"/>
Replace %msg token with %boundedMsg in your message format pattern

EBean mapping Booleans defaulting to false instead of null

I've been using Scala + EBean and I have a problem;
I have a model that looks a bit like this;
case class SomeModel(name: String) extends Model {
var someBool: Boolean = _
}
The problem is that even though the default value of someBool is null in the schema, EBean fills it up with 0 (it maps it to a TINYINT in mySQL), I should be able to save a null in the fields as well.
(ideally I'd like to keep track of whether or not the field has been set to a value in the model), wherein a null for a field would mean the field hasn't been filled in yet.
What would be the best way to solve this?
A possible solution to this is to simply replace Boolean with java.lang.Boolean, so;
case class SomeModel(name: String) extends Model {
var someBool: java.lang.Boolean = _
}

Grails Jasypt plugin Column maxsize always creates varchar instead of text for mysql

I'm trying to increase the size of the encrypted column
static mapping = {
col1 type: GormEncryptedStringType
}
static constraints = {
col1(nullable:true)
}
It always generates a varchar(255) in MySQL while I want it as a text type. I tried adding maxSize:65000 but then it creates a varchar(65000) instead of text.
This field can contain a lot of data and ideally I would want it to be LONGTEXT field.
For other non-encypted fields, I successfully used type:'text' and it worked but I am stumped since this is an encrypted field and I cant add another type.
Any help is much appreciated.
Type is the Hibernate Type. In addition to that trying adding sqlType which as the name implies is the underlying SQL column type.
static mapping = {
col1 type: GormEncryptedStringType, sqlType:'TEXT'
}
Also, depending on your 'sql type', you can also add length to change your column size
static mapping = {
col1 type: GormEncryptedStringType, sqlType:'varchar', length:400
}

how do I indicate an unset default parameter of type Number in Flex3?

for String and Object type, I can set the default parameter to null to indicate that it was not set by the caller. Is there a mechanism in flex3 to do the same for the Number type?
So for instance:
public function myMethod( stringVar:String=null, ObjectVar:Object=null, numberVar:Number )
{
...
}
I could do the following, but it just feels ugly
public function myMethod( numberVarObj:Object=null )
{
var numberVarSet:Boolean=true;
if( numberVarObj == null ) {
numberVarSet = false;
}
and then everywhere I want to use numberVar I can check for numberVarSet and cast as a Number.
I suppose you could always try:
var numberVar:* = null;
And then set it to a number when you want . . . It would be nice to have a solution that is strongly typed though.
Another option, as specified in Adobe's Docs (scroll down to default values), would be to treat the value NaN as null. However, if your data has ANY chance of containing a NaN value, this is a horrible idea.
I'd recommend the "ugly" solution you have, but if you really want another option you can use NaN and then use isNaN(num) to check the value.