You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ignite.apache.org by ptupitsyn <pt...@apache.org> on 2017/07/05 08:44:06 UTC

Re: Dymanically add QueryField on Cache Entity and perform DateTime filter.

Hi,

Please properly subscribe to the mailing list so that the community can
receive email notifications for your messages. To subscribe, send empty
email to user-subscribe@ignite.apache.org and follow simple instructions in
the reply.

I have reproduced the problem, it is caused by the fact that DateTime is
serialized in .NET-specific format by default, and this does not work in
SQL, see "DateTime and SQL" section:
https://apacheignite-net.readme.io/docs/sql-queries#section-java-type-name-mapping

To enforce SQL-compatible TimeStamp format:
1) Mark the field with [QuerySqlField]. Looks like this is not an option for
you, though, since reflection is used

2) Implement IBinarizable:

public class ABC : IBinarizable
{
	public int Id { get; set; }
	public string Name { get; set; }
	public DateTime StartTime { get; set; }

	public void WriteBinary(IBinaryWriter writer)
	{
		writer.WriteInt("Id", Id);
		writer.WriteString("Name", Name);
		writer.WriteTimestamp("StartTime", StartTime);
	}

	public void ReadBinary(IBinaryReader reader)
	{
		Id = reader.ReadInt("Id");
		Name = reader.ReadString("Name");
		StartTime = reader.ReadTimestamp("StartTime").GetValueOrDefault();
	}
}

3) Implement IBinarySerializer:

public class AbcSerializer : IBinarySerializer
{
	public void WriteBinary(object o, IBinaryWriter writer)
	{
		var abc = (ABC)o;
		
		writer.WriteInt("Id", abc.Id);
		writer.WriteString("Name", abc.Name);
		writer.WriteTimestamp("StartTime", abc.StartTime);
	}

	public void ReadBinary(object o, IBinaryReader reader)
	{
		var abc = (ABC)o;
		
		abc.Id = reader.ReadInt("Id");
		abc.Name = reader.ReadString("Name");
		abc.StartTime = reader.ReadTimestamp("StartTime").GetValueOrDefault();
	}
}

and register it in config:
		BinaryConfiguration = new BinaryConfiguration
		{
			TypeConfigurations = new[] { new BinaryTypeConfiguration(typeof(ABC)) {
Serializer = new AbcSerializer() }}
		}




--
View this message in context: http://apache-ignite-users.70518.x6.nabble.com/Dymanically-add-QueryField-on-Cache-Entity-and-perform-DateTime-filter-tp14318p14319.html
Sent from the Apache Ignite Users mailing list archive at Nabble.com.

RE: Dymanically add QueryField on Cache Entity and perform DateTime filter.

Posted by Narayana Rengaswamy <na...@optym.com>.
Thanks Pavel, it works brilliantly!

Here’s my code right now, and it is working nicely:

private BinaryConfiguration CreateBinaryConfiguration()
        {
            var binaryReflectiveSerializer = new BinaryReflectiveSerializer
                                                 {
                                                     ForceTimestamp = true
                                                 };

            var binaryTypeConfigurations = new List<BinaryTypeConfiguration>();
            foreach (var type in CacheConstant.GetDomainEntities())
            {
                var binaryTypeConfiguration = new BinaryTypeConfiguration(type)
                                                  {
                                                      Serializer = binaryReflectiveSerializer
                                                  };
                binaryTypeConfigurations.Add(binaryTypeConfiguration);
            }

            return new BinaryConfiguration
                       {
                           TypeConfigurations = binaryTypeConfigurations
                       };
        }


private ICollection<CacheConfiguration> CreateCacheConfigCollection()
        {
            var cacheConfigs = new List<CacheConfiguration>();

            foreach (var mapping in CacheConstant.GetDomainEntities())
            {
                MethodInfo method = typeof(CacheServerInitializer).GetMethod("CreateCacheConfig", BindingFlags.NonPublic | BindingFlags.Instance);
                MethodInfo generic = method.MakeGenericMethod(mapping.Key);
                var cacheConfig = (CacheConfiguration)generic.Invoke(this, null);
                cacheConfigs.Add(cacheConfig);
            }

            return cacheConfigs;
        }

        private CacheConfiguration CreateCacheConfig<T>()
            where T : DomainEntity
        {
            var type = typeof(T);
            var cacheName = CacheConstant.GetCacheName<T>();

            var queryFields = new List<QueryField>();
            foreach (var property in type.GetProperties())
            {
                var queryField = new QueryField(property.Name, property.PropertyType)
                                     {
                                         IsKeyField = property.Name == "Id"
                                     };
                queryFields.Add(queryField);
            }

            var queryEntity = new QueryEntity
                                  {
                                      KeyType = typeof(long),
                                      ValueType = type,
                                      Fields = queryFields.ToArray()
                                  };

            return new CacheConfiguration
                       {
                           Name = cacheName,
                           QueryEntities = new[] { queryEntity },
                           CacheMode = CacheMode.Replicated,
                           CacheStoreFactory = this.cacheStoreFactory.CreateCacheStoreFactory<T>(),
                           ReadThrough = true,
                           WriteThrough = true,
                           KeepBinaryInStore = false
                       };
        }


Thanks,
Narayana.

From: Pavel Tupitsyn [mailto:ptupitsyn@apache.org]
Sent: 07 July 2017 18:57
To: user@ignite.apache.org
Subject: Re: Dymanically add QueryField on Cache Entity and perform DateTime filter.

This can be tested with a nightly build right now: https://cwiki.apache.org/confluence/display/IGNITE/Nightly+Builds

> Install-Package Apache.Ignite -Pre -Source https://www.myget.org/F/apache-ignite-net-nightly

On Fri, Jul 7, 2017 at 4:26 PM, Pavel Tupitsyn <pt...@apache.org>> wrote:
Addition:

In upcoming 2.1 version there is a BinaryReflectiveSerializer.ForceTimestamp property, which makes it write any DateTime as a Timestamp.
So instead of a custom serializer, you can do this:

BinaryConfiguration = new BinaryConfiguration
                {
                        TypeConfigurations = new[] { new BinaryTypeConfiguration(typeof(ABC)) {
Serializer = new BinaryReflectiveSerializer {ForceTimestamp = true} }}
                }

On Wed, Jul 5, 2017 at 11:44 AM, ptupitsyn <pt...@apache.org>> wrote:
Hi,

Please properly subscribe to the mailing list so that the community can
receive email notifications for your messages. To subscribe, send empty
email to user-subscribe@ignite.apache.org<ma...@ignite.apache.org> and follow simple instructions in
the reply.

I have reproduced the problem, it is caused by the fact that DateTime is
serialized in .NET-specific format by default, and this does not work in
SQL, see "DateTime and SQL" section:
https://apacheignite-net.readme.io/docs/sql-queries#section-java-type-name-mapping

To enforce SQL-compatible TimeStamp format:
1) Mark the field with [QuerySqlField]. Looks like this is not an option for
you, though, since reflection is used

2) Implement IBinarizable:

public class ABC : IBinarizable
{
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime StartTime { get; set; }

        public void WriteBinary(IBinaryWriter writer)
        {
                writer.WriteInt("Id", Id);
                writer.WriteString("Name", Name);
                writer.WriteTimestamp("StartTime", StartTime);
        }

        public void ReadBinary(IBinaryReader reader)
        {
                Id = reader.ReadInt("Id");
                Name = reader.ReadString("Name");
                StartTime = reader.ReadTimestamp("StartTime").GetValueOrDefault();
        }
}

3) Implement IBinarySerializer:

public class AbcSerializer : IBinarySerializer
{
        public void WriteBinary(object o, IBinaryWriter writer)
        {
                var abc = (ABC)o;

                writer.WriteInt("Id", abc.Id);
                writer.WriteString("Name", abc.Name);
                writer.WriteTimestamp("StartTime", abc.StartTime);
        }

        public void ReadBinary(object o, IBinaryReader reader)
        {
                var abc = (ABC)o;

                abc.Id = reader.ReadInt("Id");
                abc.Name = reader.ReadString("Name");
                abc.StartTime = reader.ReadTimestamp("StartTime").GetValueOrDefault();
        }
}

and register it in config:
                BinaryConfiguration = new BinaryConfiguration
                {
                        TypeConfigurations = new[] { new BinaryTypeConfiguration(typeof(ABC)) {
Serializer = new AbcSerializer() }}
                }




--
View this message in context: http://apache-ignite-users.70518.x6.nabble.com/Dymanically-add-QueryField-on-Cache-Entity-and-perform-DateTime-filter-tp14318p14319.html
Sent from the Apache Ignite Users mailing list archive at Nabble.com.



Re: Dymanically add QueryField on Cache Entity and perform DateTime filter.

Posted by Pavel Tupitsyn <pt...@apache.org>.
This can be tested with a nightly build right now:
https://cwiki.apache.org/confluence/display/IGNITE/Nightly+Builds

> Install-Package Apache.Ignite -Pre -Source
https://www.myget.org/F/apache-ignite-net-nightly

On Fri, Jul 7, 2017 at 4:26 PM, Pavel Tupitsyn <pt...@apache.org> wrote:

> Addition:
>
> In upcoming 2.1 version there is a BinaryReflectiveSerializer.F
> orceTimestamp property, which makes it write any DateTime as a Timestamp.
> So instead of a custom serializer, you can do this:
>
> BinaryConfiguration = new BinaryConfiguration
>                 {
>                         TypeConfigurations = new[] { new
> BinaryTypeConfiguration(typeof(ABC)) {
> Serializer = new BinaryReflectiveSerializer {ForceTimestamp = true} }}
>                 }
>
> On Wed, Jul 5, 2017 at 11:44 AM, ptupitsyn <pt...@apache.org> wrote:
>
>> Hi,
>>
>> Please properly subscribe to the mailing list so that the community can
>> receive email notifications for your messages. To subscribe, send empty
>> email to user-subscribe@ignite.apache.org and follow simple instructions
>> in
>> the reply.
>>
>> I have reproduced the problem, it is caused by the fact that DateTime is
>> serialized in .NET-specific format by default, and this does not work in
>> SQL, see "DateTime and SQL" section:
>> https://apacheignite-net.readme.io/docs/sql-queries#section-
>> java-type-name-mapping
>>
>> To enforce SQL-compatible TimeStamp format:
>> 1) Mark the field with [QuerySqlField]. Looks like this is not an option
>> for
>> you, though, since reflection is used
>>
>> 2) Implement IBinarizable:
>>
>> public class ABC : IBinarizable
>> {
>>         public int Id { get; set; }
>>         public string Name { get; set; }
>>         public DateTime StartTime { get; set; }
>>
>>         public void WriteBinary(IBinaryWriter writer)
>>         {
>>                 writer.WriteInt("Id", Id);
>>                 writer.WriteString("Name", Name);
>>                 writer.WriteTimestamp("StartTime", StartTime);
>>         }
>>
>>         public void ReadBinary(IBinaryReader reader)
>>         {
>>                 Id = reader.ReadInt("Id");
>>                 Name = reader.ReadString("Name");
>>                 StartTime = reader.ReadTimestamp("StartTim
>> e").GetValueOrDefault();
>>         }
>> }
>>
>> 3) Implement IBinarySerializer:
>>
>> public class AbcSerializer : IBinarySerializer
>> {
>>         public void WriteBinary(object o, IBinaryWriter writer)
>>         {
>>                 var abc = (ABC)o;
>>
>>                 writer.WriteInt("Id", abc.Id);
>>                 writer.WriteString("Name", abc.Name);
>>                 writer.WriteTimestamp("StartTime", abc.StartTime);
>>         }
>>
>>         public void ReadBinary(object o, IBinaryReader reader)
>>         {
>>                 var abc = (ABC)o;
>>
>>                 abc.Id = reader.ReadInt("Id");
>>                 abc.Name = reader.ReadString("Name");
>>                 abc.StartTime = reader.ReadTimestamp("StartTim
>> e").GetValueOrDefault();
>>         }
>> }
>>
>> and register it in config:
>>                 BinaryConfiguration = new BinaryConfiguration
>>                 {
>>                         TypeConfigurations = new[] { new
>> BinaryTypeConfiguration(typeof(ABC)) {
>> Serializer = new AbcSerializer() }}
>>                 }
>>
>>
>>
>>
>> --
>> View this message in context: http://apache-ignite-users.705
>> 18.x6.nabble.com/Dymanically-add-QueryField-on-Cache-
>> Entity-and-perform-DateTime-filter-tp14318p14319.html
>> Sent from the Apache Ignite Users mailing list archive at Nabble.com.
>>
>
>

Re: Dymanically add QueryField on Cache Entity and perform DateTime filter.

Posted by Pavel Tupitsyn <pt...@apache.org>.
Addition:

In upcoming 2.1 version there is a BinaryReflectiveSerializer.
ForceTimestamp property, which makes it write any DateTime as a Timestamp.
So instead of a custom serializer, you can do this:

BinaryConfiguration = new BinaryConfiguration
                {
                        TypeConfigurations = new[] { new
BinaryTypeConfiguration(typeof(ABC)) {
Serializer = new BinaryReflectiveSerializer {ForceTimestamp = true} }}
                }

On Wed, Jul 5, 2017 at 11:44 AM, ptupitsyn <pt...@apache.org> wrote:

> Hi,
>
> Please properly subscribe to the mailing list so that the community can
> receive email notifications for your messages. To subscribe, send empty
> email to user-subscribe@ignite.apache.org and follow simple instructions
> in
> the reply.
>
> I have reproduced the problem, it is caused by the fact that DateTime is
> serialized in .NET-specific format by default, and this does not work in
> SQL, see "DateTime and SQL" section:
> https://apacheignite-net.readme.io/docs/sql-queries#
> section-java-type-name-mapping
>
> To enforce SQL-compatible TimeStamp format:
> 1) Mark the field with [QuerySqlField]. Looks like this is not an option
> for
> you, though, since reflection is used
>
> 2) Implement IBinarizable:
>
> public class ABC : IBinarizable
> {
>         public int Id { get; set; }
>         public string Name { get; set; }
>         public DateTime StartTime { get; set; }
>
>         public void WriteBinary(IBinaryWriter writer)
>         {
>                 writer.WriteInt("Id", Id);
>                 writer.WriteString("Name", Name);
>                 writer.WriteTimestamp("StartTime", StartTime);
>         }
>
>         public void ReadBinary(IBinaryReader reader)
>         {
>                 Id = reader.ReadInt("Id");
>                 Name = reader.ReadString("Name");
>                 StartTime = reader.ReadTimestamp("
> StartTime").GetValueOrDefault();
>         }
> }
>
> 3) Implement IBinarySerializer:
>
> public class AbcSerializer : IBinarySerializer
> {
>         public void WriteBinary(object o, IBinaryWriter writer)
>         {
>                 var abc = (ABC)o;
>
>                 writer.WriteInt("Id", abc.Id);
>                 writer.WriteString("Name", abc.Name);
>                 writer.WriteTimestamp("StartTime", abc.StartTime);
>         }
>
>         public void ReadBinary(object o, IBinaryReader reader)
>         {
>                 var abc = (ABC)o;
>
>                 abc.Id = reader.ReadInt("Id");
>                 abc.Name = reader.ReadString("Name");
>                 abc.StartTime = reader.ReadTimestamp("
> StartTime").GetValueOrDefault();
>         }
> }
>
> and register it in config:
>                 BinaryConfiguration = new BinaryConfiguration
>                 {
>                         TypeConfigurations = new[] { new
> BinaryTypeConfiguration(typeof(ABC)) {
> Serializer = new AbcSerializer() }}
>                 }
>
>
>
>
> --
> View this message in context: http://apache-ignite-users.
> 70518.x6.nabble.com/Dymanically-add-QueryField-on-
> Cache-Entity-and-perform-DateTime-filter-tp14318p14319.html
> Sent from the Apache Ignite Users mailing list archive at Nabble.com.
>