Save succesfully done, but elements are not in the view

Oct 6, 2015 at 11:31 AM
I have a collection of cca 2k objects I need to index. The definitions are as follows:
    public class TmElementInfo
    {
        public TmElementInfo()
        {
            this.ID = Guid.NewGuid();
        }
        public Guid ID { get; set;}
        public UInt32 LocalID { get; set;}
        public UInt32 TMB_ID { get; set;}
        public UInt32 TMC_ID { get; set;}
        public UInt16 TME_ORD { get; set;}
        public char TME_ATTR { get; set;}
        public char TME_WEIGHT { get; set;}
        public UInt16 TME_POS1 { get; set;}
        public UInt16 TME_POS2 { get; set;}
        public UInt16 TME_POS3 { get; set;}
        public UInt16 TME_POS4 { get; set;}
        public UInt32 DLW_ID { get; set;}
        public Int16 NMT_ID { get; set;}
        public string DLW_TEXT { get; set;}
    }

    public class TmElementInfoSchema : RDBSchema
    {
        public UInt32 LocalID;
        public UInt32 TMB_ID;
        public UInt32 TMC_ID;
        public UInt16 TME_ORD;
        public char TME_ATTR;
        public char TME_WEIGHT;
        public UInt16 TME_POS1;
        public UInt16 TME_POS2;
        public UInt16 TME_POS3;
        public UInt16 TME_POS4;
        public UInt32 DLW_ID;
        public Int16 NMT_ID;
        public string DLW_TEXT;
    }

    [RegisterView]
    public class TmElementInfoView : RaptorDB.View<TmElementInfo>
    {
        public TmElementInfoView()
        {
            this.Name = "TmElementInfoView";
            this.Description = "Storage for tm elements";
            this.isPrimaryList = false;
            this.BackgroundIndexing = false;
            this.Schema = typeof(TmElementInfoSchema);
            this.TransactionMode = false;
            this.Version = 1;
            this.DeleteBeforeInsert = false;
            this.Mapper = (api, docid, doc) =>
            {
                api.EmitObject(docid, doc);
            };
        }
    }
and the code looks like
    this.rdb = RaptorDB.RaptorDB.Open(rdb_path);
    // registering other 3 working views
    this.rdb.RegisterView(new TmNameInfoView());
    
    // previous 3 `views` were loaded here and they all worked fine, the code is similar with the one below
    foreach (var entry in collection)
    {
        TmElementInfo tei = new TmElementInfo()
        {
            LocalID = ++local_index_token,
            // populate all properties
        };
        
        if (!this.rdb.Save<TmElementInfo>(tei.ID, tei))
        {
            throw new Exception("save failed!");
        }
        
        Log("saved {0} ... and other properties here", tei.ID.ToString(), )
    }
and when I count the objects available in the collection:
int z = this.rdb.Count<TmElementInfoSchema>(x => x.TMB_ID > 0);
I get always 0. I checked the size of the files on disk for TmElementInfoView and the size before and after the loop run is the same. Initially, I thought it has something to do with background indexing (btw: it looks like I have to wait a while until all is indexed even if BackgroundIndexing is false). I tweaked the value, I waited in both cases (true/false) - but the result is the same.

For example, I am running this query: "TMB_ID=10 and TMC_ID=11 and TME_ORD=5 and NMT_ID=1". I checked the log and the object with these values is created, saved (!?), but when I run the query - the result is empty.

Am I doing something wrong here? Is there some kind of limitation I am not aware of? Is it something related to the number of views I opened? Or the data in my objects? Other schemas are somehow similar and they worked ... I checked all kind of queries for all my views, and this one is the only one that returns no results. No errors (Result<T>.Ok is true), no exceptions (Result<T>.EX is null), just empty sets (Rows.Count and TotalCount are 0).
Oct 6, 2015 at 12:30 PM
1) Check the logs.
2) When is entry used?
3) Try rdb.Query<TmElementInfoSchema>("");
Oct 6, 2015 at 12:42 PM
Edited Oct 6, 2015 at 12:47 PM
1) I checked the logs. There is nothing in there. For example, to populate the TmElementInfoView collection, I occasionally read from other views. I only see those read-queries logged there, with the text-query (made it on purpose text to see it in logs), the timing (mostly 0) and the results fetched (1-2 rows).

I started the logs like this:
RaptorDB.LogManager.Configure(@"C:\logs\raptor.log", 1024, true);
RaptorDB.LogManager.Shutdown();
I am not sure if I should have provided any other flags for logging-initialization, but the DEBUG messages were already there so I assumed this should be enough.

2) entry is actually a double loop between an SqlDataReader and Rows from those queries made on #1;

3) returns the same: Rows.Count = 0, TotalCount = 0.
Oct 6, 2015 at 1:16 PM
the logging between 2 Save calls is:
2015-10-06 14:07:54|INFO|25|Service.CollectionBuilder.Run|MoveNext|  ++ Next tmb_id: 1234, tmc_id: 8541
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|Query2| query : TmNameInfoView
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|Query2| query : TMB_ID=1234 and NMT_ID=1
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|Query2| order by : 
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|Query2| query bitmap done (ms) : 1.0001
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|ReturnRows2| query rows fetched (ms) : 0
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|ReturnRows2| query rows count : 1
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|Query2| query : TmNameInfoView
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|Query2| query : TMB_ID=1234 and TMC_ID=8541
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|Query2| order by : 
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|Query2| query bitmap done (ms) : 0
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|ReturnRows2| query rows fetched (ms) : 0
2015-10-06 14:07:54|DEBUG|25|RaptorDB.Views.ViewHandler|ReturnRows2| query rows count : 1
2015-10-06 14:07:54|INFO|25|Service.CollectionBuilder.Run|MoveNext|  ++ Called Save<TmElementInfo> on tmb_id: 1234, tmc_id: 8541 - saved local id: 1965
The last line of logging is made right after rdb.Save<TmElementInfo> was called. The rest of the logging within the loop looks similar. The initialization logging for TmElementInfoView looks identical with the one generated by other views. One comment - it says always about upgrading/deleting the old view-data-folder even if the folder is new - but I assume this is normal.
Oct 6, 2015 at 1:41 PM
RaptorDB handles the logs you are not supposed to Configure() and Shutdown() yourself and certainly not one after the other.
Oct 6, 2015 at 1:46 PM
Edited Oct 6, 2015 at 1:48 PM
I didn't. It was just to show you how I used them - hoping they were verbose enough. Anyway, I guess/hope the problem is not there. ;-)

I did a little bit more researching and it looks like the saving fails due some invalid cast exception. Save<> returns true, but it crashes later ... the stack is here:
System.InvalidCastException: {"Specified cast is not valid."}
HResult: -2147467262
StackTrace:
   at _(Object , Object )
   at fastBinaryJSON.deserializer.ParseDictionary(Dictionary`2 d, Dictionary`2 globaltypes, Type type, Object input) in c:\Work\raptordb\RaptorDB.Common\fastBinaryJSON\BJSON.cs:line 532
   at fastBinaryJSON.deserializer.ToObject(Byte[] json, Type type) in c:\Work\raptordb\RaptorDB.Common\fastBinaryJSON\BJSON.cs:line 298
   at fastBinaryJSON.BJSON.ToObject(Byte[] json) in c:\Work\raptordb\RaptorDB.Common\fastBinaryJSON\BJSON.cs:line 213
   at RaptorDB.StorageFile`1.ReadObject(Int64 recnum, StorageItem`1& meta) in c:\Work\raptordb\RaptorDB\Storage\StorageFile.cs:line 314
   at RaptorDB.KeyStore`1.GetObject(Int32 rowid, StorageItem`1& meta) in c:\Work\raptordb\RaptorDB\Storage\KeyStore.cs:line 593
   at RaptorDB.RaptorDB._saveTimer_Elapsed(Object sender, ElapsedEventArgs e) in c:\Work\raptordb\RaptorDB\RaptorDB.cs:line 1175
   at System.Timers.Timer.MyTimerCallback(Object state)
Oct 6, 2015 at 1:57 PM
Apparently, it has something to do with char typed properties - it crashes when it tries to save TME_ATTR property from the pi json dictionary.
Oct 6, 2015 at 2:02 PM
Ah!

Missed that!

I believe you can use byte but char is not supported in views (I will fix this).
Oct 6, 2015 at 2:08 PM
Will do that!

Do I need to change only in Schema class or do I need to change in both classes (TmElementInfo and TmElementInfoSchema)? By the way - what is the logic between those 2 classes? Why do I need to define always 2 for the same view/collection? It's a little bit confusing because when I add a new element, I use Save<TmElementInfo>, but when I read I need to use Query<TmElementInfoSchema> ...
Oct 6, 2015 at 2:45 PM
Yes only in the schema, so the view insert works (I'm not sure if the the auto convert works when you api.EmitObject() you will have to try and see - let me know).

Your "entity" classes are for your application domain, the "schema" class are for your views/queries.

Save() takes your entity and may have multiple views associated with different parts of it and different query types, Query<T>() takes the T and infers the view to query from.

Hope that makes sense.