Exemple #1
0
        /// <exception cref="InvalidOperationException">Missed secondary key for some criterion.</exception>
        public virtual IEnumerable <DatabaseEntry> GetByJoin(IBDbEntityInfo info, ICollection <IDataCriterion> criteria)
        {
            var        cursorsLength    = 0;
            var        secondaryCursors = new SecondaryCursor[criteria.Count];
            JoinCursor joinCursor       = null;

            try {
                var primaryDb = _schema.GetPrimaryDb(info.EntityName);

                foreach (var criterion in criteria)
                {
                    SecondaryKeyAttribute secondaryKey;
                    if (!info.SecondaryKeys.TryGetValue(criterion.Name, out secondaryKey))
                    {
                        var msg = $"Missed secondaty key '{criterion.Name}' for entity {info.EntityName} ({info.EntityType}).";
                        Log.TraceEvent(TraceEventType.Critical, msg);
                        throw new InvalidOperationException(msg);
                    }

                    var secondaryDb = _schema.GetSecondaryDb(primaryDb, secondaryKey);

                    var cursor = secondaryDb.SecondaryCursor();
                    secondaryCursors[cursorsLength++] = cursor;

                    var key = new DatabaseEntry(criterion.Value.ToBinnary());
                    if (!cursor.Move(key, exact:true))
                    {
                        yield break;
                    }
                }

                joinCursor = primaryDb.Join(secondaryCursors, true);
                while (joinCursor.MoveNext())
                {
                    yield return(joinCursor.Current.Value);
                }
            }
            finally {
                joinCursor?.Close();

                for (var i = 0; i < cursorsLength; i++)
                {
                    secondaryCursors[i].Close();
                }
            }
        }
Exemple #2
0
        public void TestJoin()
        {
            testName = "TestJoin";
            testHome = testFixtureHome + "/" + testName;
            string dbFileName   = testHome + "/" + testName + ".db";
            string secFileName1 = testHome + "/" + "sec_" + testName + "1.db";
            string secFileName2 = testHome + "/" + "sec_" + testName + "2.db";

            Configuration.ClearDir(testHome);

            // Open a primary database.
            BTreeDatabaseConfig dbCfg = new BTreeDatabaseConfig();

            dbCfg.Creation = CreatePolicy.IF_NEEDED;
            BTreeDatabase db = BTreeDatabase.Open(dbFileName, dbCfg);

            /*
             * Open two databases, their secondary databases and
             * secondary cursors.
             */
            SecondaryBTreeDatabase secDB1, secDB2;

            SecondaryCursor[] cursors = new SecondaryCursor[2];
            GetSecCursor(db, secFileName1,
                         new SecondaryKeyGenDelegate(KeyGenOnBigByte),
                         out secDB1, out cursors[0], false, null);
            GetSecCursor(db, secFileName2,
                         new SecondaryKeyGenDelegate(KeyGenOnLittleByte),
                         out secDB2, out cursors[1], true, null);

            // Get join cursor.
            JoinCursor joinCursor = db.Join(cursors, true);

            // Close all.
            joinCursor.Close();
            cursors[0].Close();
            cursors[1].Close();
            secDB1.Close();
            secDB2.Close();
            db.Close();
        }
        public void TestMoveJoinCursor()
        {
            testName = "TestMoveJoinCursor";
            SetUpTest(true);
            string dbFileName   = testHome + "/" + testName + ".db";
            string secFileName1 = testHome + "/" + "sec_" + testName + "1.db";
            string secFileName2 = testHome + "/" + "sec_" + testName + "2.db";

            // Open a primary database.
            BTreeDatabaseConfig dbCfg = new BTreeDatabaseConfig();

            dbCfg.Creation = CreatePolicy.IF_NEEDED;
            BTreeDatabase db = BTreeDatabase.Open(dbFileName, dbCfg);

            /*
             * Open a secondary database on high byte of
             * its data and another secondary database on
             * little byte of its data.
             */
            SecondaryBTreeDatabase secDB1, secDB2;

            SecondaryCursor[] cursors   = new SecondaryCursor[2];
            byte[]            byteValue = new byte[1];

            byteValue[0] = 0;
            GetSecCursor(db, secFileName1,
                         new SecondaryKeyGenDelegate(KeyGenOnBigByte),
                         out secDB1, out cursors[0], false,
                         new DatabaseEntry(byteValue));

            byteValue[0] = 1;
            GetSecCursor(db, secFileName2,
                         new SecondaryKeyGenDelegate(KeyGenOnLittleByte),
                         out secDB2, out cursors[1], true,
                         new DatabaseEntry(byteValue));

            // Get join cursor.
            JoinCursor joinCursor = db.Join(cursors, true);

            /*
             * MoveNextJoinItem do not use data value found
             * in all of the cursor so the data in Current won't be
             * changed.
             */
            Assert.IsTrue(joinCursor.MoveNextItem());
            Assert.AreEqual(0, joinCursor.Current.Key.Data[
                                joinCursor.Current.Key.Data.Length - 1]);
            Assert.AreEqual(1, joinCursor.Current.Key.Data[0]);
            Assert.IsNull(joinCursor.Current.Value.Data);

            // Iterate on join cursor.
            foreach (KeyValuePair <DatabaseEntry, DatabaseEntry> pair in joinCursor)
            {
                /*
                 * Confirm that the key got by join cursor has 0 at
                 * its highest byte and 1 at its lowest byte.
                 */
                Assert.AreEqual(0, pair.Key.Data[pair.Key.Data.Length - 1]);
                Assert.AreEqual(1, pair.Key.Data[0]);
            }

            Assert.IsFalse(joinCursor.MoveNext());

            // Close all.
            joinCursor.Close();
            cursors[0].Close();
            cursors[1].Close();
            secDB1.Close();
            secDB2.Close();
            db.Close();
        }