Can I set min/max value of database sequence from Entity? - spring

Is there a way where I can the sequence max and min value from the entity itself

I don't think that it is possible to create a sequence with specific MINVALUE or MAXVALUE by using JPA or Hibernate.
The JPA specific annotation for this task is the SequenceGenerator which does not accept the MINVALUE or the MAXVALUE. It optionally accepts the initialValue which affects the "STARTS WITH" value of the sequence and probably implicitly sets the MINVALUE or the MAXVALUE.
For example the Oracle database says regarding the CREATE SEQUENCE statement:
START WITH
Specify the first sequence number to be generated. Use
this clause to start an ascending sequence at a value greater than its
minimum or to start a descending sequence at a value less than its
maximum. For ascending sequences, the default value is the minimum
value of the sequence. For descending sequences, the default value is
the maximum value of the sequence. This integer value can have 28 or
fewer digits.
There is the hibernate specific API GenericGenerator and SequenceStyleGenerator which can be used to create a sequence (see an example) but they too seem not to accept MINVLAUE or MAXVALUE as parameters.
Finally, a quick look into Hibernate's code for Oracle DB suggests that indeed the MINVALUE AND MAXVALUE is set implicitly based on the provided initialValue as the Oracle documentation above suggests. For example here is the relevant code:
protected String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize) {
if ( initialValue < 0 && incrementSize > 0 ) {
return
String.format(
"%s minvalue %d start with %d increment by %d",
getCreateSequenceString( sequenceName ),
initialValue,
initialValue,
incrementSize
);
}
else if ( initialValue > 0 && incrementSize < 0 ) {
return
String.format(
"%s maxvalue %d start with %d increment by %d",
getCreateSequenceString( sequenceName ),
initialValue,
initialValue,
incrementSize
);
}
else {
return
String.format(
"%s start with %d increment by %d",
getCreateSequenceString( sequenceName ),
initialValue,
incrementSize
);
}
}
I assume that this should be the case for other databases except Oracle that support sequences too.

Related

Find newest Revisions of Entities where timestamp is less than x

I've made a painting to illustrate my desired result:
painting of the result
I have a max timestamp that i pass to my backend and i want to return the newest versions of the Entities that have a timestamp that is less than the passed one.
The passed timestamp in my example is 180. I've kept the numbers low so that it is easier to visualize.
This is a combination of a horizontal and a vertical Query and i'm not sure how i can achieve that.
Any help would be appreciated!
It can be achieved with the following:
public List<Book> getBooksByMaxTimestamp(Date date) {
String formattedDate = simpleDateFormat.format(date);
System.out.println("Less than " + formattedDate);
AuditQuery maxRevisionNumberQuery = auditReader.createQuery().forRevisionsOfEntity(Book.class, true, false);
maxRevisionNumberQuery.add(AuditEntity.revisionProperty("timestamp").le(date.getTime()));
maxRevisionNumberQuery.addProjection(AuditEntity.revisionNumber().max());
int maxRevisionNumber = (int) maxRevisionNumberQuery.getSingleResult();
AuditQuery auditQuery = auditReader.createQuery().forEntitiesAtRevision(Book.class, maxRevisionNumber);
return auditQuery.getResultList();
}
First we get the max revision number that is in that range and after that we use that number to get the entities that we want.

Is Clickhouse primary key first row of the granule or not?

I read the clickhouse doc, it seem to be not.
Index entries (index marks) are not based on specific rows from our table but on granules. E.g. for index entry ‘mark 0’ in the diagram above there is no row in our table where UserID is 240.923 and URL is "goal://metry=10000467796a411...", instead, there is a granule 0 for the table where within that granule the minimum UserID vale is 240.923 and the minimum URL value is "goal://metry=10000467796a411..." and these two values are from separate rows.
But by source code primaty key column value is from granule.start_row.
for (const auto & granule : granules_to_write)
{
if (metadata_snapshot->hasPrimaryKey() && granule.mark_on_start)
{
for (size_t j = 0; j < primary_columns_num; ++j)
{
const auto & primary_column = primary_index_block.getByPosition(j);
index_columns[j]->insertFrom(*primary_column.column, granule.start_row);
primary_column.type->getDefaultSerialization()->serializeBinary(*primary_column.column, granule.start_row, *index_stream);
}
}
}
I'm confused,doc is wrong?

Setting Linq2Db to read and update with CHAR type and NOT NULL constraint in Oracle

Reading value of fixed CHAR string from table, using Linq2db Oracle provider:
CREATE TABLE mytable
(pk NUMBER(15,0) NOT NULL,
fixed_data CHAR(20) DEFAULT ' ' NOT NULL)
Although in database, length of FIXED_DATA filed is 20,
SELECT LENGTH(fixed_data) FROM mytable WHERE pk = 1
-- result is 20
When same field is read using Linq2Db, value gets truncated to empty string:
var row = (from row in database.mytable where row.pk == 1 select row).ToList()[0];
Console.WriteLine(row.fixed_data.Length);
// result is zero
This causes problem when record is updated using Linq2Db, Oracle converts empty string to NULL, and UPDATE fails:
database.Update(row);
// Oracle.ManagedDataAccess.Client.OracleException: 'ORA-01407: cannot update ("MYSCHEMA"."MYTABLE"."FIXED_DATA") to NULL
Is there any setting in Linq2Db for read->update cycle to work with CHAR type and NOT NULL constraint?
Found a solution, thanks to source code openly available. By default, Linq2Db calls expression IDataReader.GetString(int).TrimEnd(' ') on every CHAR and NCHAR column. However this can be easily customized, by implementing custom provider, which overrides field value retrieval expression, with one that does not trim:
class MyOracleProvider : OracleDataProvider
{
public MyOracleProvider(string name)
: base(name)
{
// original is SetCharField("Char", (r,i) => r.GetString(i).TrimEnd(' '));
SetCharField("Char", (r, i) => r.GetString(i));
// original is SetCharField("NChar", (r,i) => r.GetString(i).TrimEnd(' '));
SetCharField("NChar", (r, i) => r.GetString(i));
}
}

DAX IF measure - return fixed value

This should be a very simple requirement. But it seems impossible to implement in DAX.
Data model, User lookup table joined to many "Cards" linked to each user.
I have a measure setup to count rows in CardUser. That is working fine.
<measureA> = count rows in CardUser
I want to create a new measure,
<measureB> = IF(User.boolean = 1,<measureA>, 16)
If User.boolean = 1, I want to return a fixed value of 16. Effectively, bypassing measureA.
I can't simply put User.boolean = 1 in the IF condition, throws an error.
I can modify measureA itself to return 0 if User.boolean = 1
measureA> =
CALCULATE (
COUNTROWS(CardUser),
FILTER ( User.boolean != 1 )
)
This works, but I still can't find a way to return 16 ONLY if User.boolean = 1.
That's easy in DAX, you just need to learn "X" functions (aka "Iterators"):
Measure B =
SUMX( VALUES(User.boolean),
IF(User.Boolean, [Measure A], 16))
VALUES function generates a list of distinct user.boolean values (1, 0 in this case). Then, SUMX iterates this list, and applies IF logic to each record.

How can I validate Ext.form.DateField using min/maxValue, without using time?

I'm having the following problem: I want to validate a DateField so that it has a value between the minValue / maxValue range. (greater or equal, lower or equal)
The problem is that I think the framework takes the time in milliseconds.
I've tried using a custom vtype such as:
Ext.apply(Ext.form.VTypes,{
dates: function(val, field){
try{
if(this.disabled){
return true;
}
if(Ext.value(val,null,false)==null){
this.datesText = "This field is required.";
return this.allowBlank; //the text message won't be shown in case blank is allowed.
}
if(Ext.value(field.minValue,null,false)!=null){
if(Ext.util.Format.date(val,"Ymd")<Ext.util.Format.date(field.minValue,"Ymd")){
this.datesText = "The value is invalid.<br/>";
this.datesText = "it must be greater or equal than " + field.minValue;
return false;
}
}
if(Ext.value(field.maxValue,null,false)!=null){
if(Ext.util.Format.date(val,"Ymd")>Ext.util.Format.date(field.maxValue,"Ymd")){
this.datesText = "The value is invalid.<br/>";
this.datesText = "It must be lower or equal than " + field.maxValue;
return false;
}
}
return true;
}catch(e){
return false;
}
},
datesText: 'The value is invalid.', //error message
datesMask: / / //regexp to filter the characters allowed
});
Basically what it does is convert the values to a 'Ymd' format and then compare values as numbers.
If I debug this code, the validation goes okay, but for some reason I still get an error message. I believe the framework is trying to validate the field again after my validation.
Thank you!
Sebastián
minValue : Date/String
The minimum allowed date. Can be either a Javascript date object or a string date in a valid format (defaults to null).
maxValue : Date/String
The maximum allowed date. Can be either a Javascript date object or a string date in a valid format (defaults to null).
and in case you needed to disable some dates
disabledDates : Array
An array of "dates" to disable, as strings. These strings will be used to build a dynamic regular expression so they are very powerful. Some examples:
// disable these exact dates:
disabledDates: ["03/08/2003", "09/16/2003"]
// disable these days for every year:
disabledDates: ["03/08", "09/16"]
// only match the beginning (useful if you are using short years):
disabledDates: ["^03/08"]
// disable every day in March 2006:
disabledDates: ["03/../2006"]
// disable every day in every March:
disabledDates: ["^03"]
Instead of fixed dates mentioned above, use this:
//doesn't allow past today
maxValue: new Date()
//Only allows 7 days in the past from current date.
minValue: Ext.Date.add(new Date(), Ext.Date.DAY, -7)

Resources