public void CachingDataLoaderFactory_InvokesLatch()
        {
            var latchMock = new DataLoaderConfigurationLatchMock();
            var dataLoaderStub = new FakeDataLoader();
            var table = new TableDescription("table", Enumerable.Empty<ColumnDescription>());
            var storeProxy = CreateFakeStoreProxy();

            ITableDataLoaderFactory factory =
                new CachingTableDataLoaderFactory(dataLoaderStub, latchMock, storeProxy);

            // The latch should not have been invoked yet
            Assert.AreEqual(0, latchMock.AcquireCallCount);
            Assert.AreEqual(0, latchMock.ReleaseCallCount);

            using (factory)
            {
                // This invocation should make the factory using the latch
                factory.CreateTableDataLoader(table);

                // The latch should have been acquired
                Assert.AreEqual(1, latchMock.AcquireCallCount);
                Assert.AreEqual(0, latchMock.ReleaseCallCount);
            }

            // The latch should have been released
            Assert.AreEqual(1, latchMock.AcquireCallCount);
            Assert.AreEqual(1, latchMock.ReleaseCallCount);
        }
Ejemplo n.º 2
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="CsvTableDataLoader" /> class.
 /// </summary>
 /// <param name="file"> The file reference to the CSV file. </param>
 /// <param name="table"> The metadata of the requested table. </param>
 public CsvTableDataLoader(IFileReference file, TableDescription table) 
     : base(table)
 {
     // TODO: Constructor injection
     this.valueConverter = new CsvValueConverter();
     this.file = file;
 }
Ejemplo n.º 3
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="EntityTableDataLoader" /> class.
 /// </summary>
 /// <param name="connection"> The connection towards the database. </param>
 /// <param name="table"> The metadata of the table. </param>
 public EntityTableDataLoader(EntityConnection connection, TableDescription table)
     : base(table)
 {
     this.connection = connection;
     this.workspace = connection.GetMetadataWorkspace();
     this.entitySet = MetadataWorkspaceHelper
         .GetEntityContainer(this.workspace)
         .GetEntitySetByName(table.Name, true);
 }
        /// <summary>
        ///     Ensures that a connection is established towards to appropriate database and 
        ///     creates a <see cref="EntityTableDataLoader" /> instance for the specified
        ///     table.
        /// </summary>
        /// <param name="table"> 
        ///     The metadata of the table.
        /// </param>
        /// <returns>
        ///     The <see cref="EntityTableDataLoader" /> instance for the table.
        /// </returns>
        public ITableDataLoader CreateTableDataLoader(TableDescription table)
        {
            if (this.connection == null)
            {
                this.connection = this.connectionFactory.Invoke();
                this.connection.Open();
            }

            return new EntityTableDataLoader(this.connection, table);
        }
 /// <summary>
 /// Creates a data loader for the specified table.
 /// </summary>
 /// <param name="table">The metadata of the table.</param>
 /// <returns>
 /// The data loader for the table.
 /// </returns>
 public ITableDataLoader CreateTableDataLoader(TableDescription table)
 {
     if (!data.HasTable(table.Name)) return new EmptyTableDataLoader();
     var entityType = data.TableType(table.Name);
     var type = LoaderType.MakeGenericType(entityType);
     var constructor = type.GetConstructor(new[]
     {
         typeof (TableDescription), 
         typeof (IEnumerable<>).MakeGenericType(entityType)
     });
     return (ITableDataLoader)constructor.Invoke(new[] { table, data.GetTable(table.Name) });
 }
        /// <summary>
        ///     Creates a <see cref="CsvTableDataLoader" /> instance for the specified table.
        /// </summary>
        /// <param name="table">
        ///     The metadata of the table. 
        /// </param>
        /// <returns>
        ///     The <see cref="CsvTableDataLoader" /> instance for the table.
        /// </returns>
        public ITableDataLoader CreateTableDataLoader(TableDescription table)
        {
            string name = string.Format("{0}.csv", table.Name);
            IFileReference file = this.source.GetFile(name);

            if (file == null || !file.Exists)
            {
                return new EmptyTableDataLoader();
            }

            return new CsvTableDataLoader(file, table);
        }
        public ITableDataLoader CreateTableDataLoader(TableDescription tableDescription)
        {
            if (tableDescription == null)
                throw new ArgumentNullException("tableDescription");

            if (!_bindings.ContainsKey(tableDescription.Name))
                return new EmptyTableDataLoader();

            var entry = _bindings.Single(x => x.Key == tableDescription.Name);

            return new EntityObjectDataLoaderWrapper(
                (IEntityDataLoader<object>)Activator.CreateInstance(Type.GetType(entry.Value, throwOnError: false)),
                tableDescription.Columns
            );
        }
        public void CachingDataLoaderFactory_IgnoresLatch()
        {
            var latchMock = new DataLoaderConfigurationLatchMock();
            var stub = new FakeDataLoader();
            var storeProxy = CreateFakeStoreProxy();
            var table = new TableDescription("table", Enumerable.Empty<ColumnDescription>());

            ITableDataLoaderFactory factory =
                new CachingTableDataLoaderFactory(stub, latchMock, storeProxy);

            using (factory)
            {
                // The CreateTableDataLoader is not invoked
            }

            // The latch should not have been invoked
            Assert.AreEqual(0, latchMock.AcquireCallCount);
        }
        public void CachingDataLoaderFactory_SingleTablesSingleQuery()
        {
            var dataLoaderMock = new FakeDataLoader();
            var storeProxy = CreateFakeStoreProxy();

            ITableDataLoaderFactory factory = 
                new CachingTableDataLoaderFactory(dataLoaderMock, null, storeProxy);

            // First call
            var table = new TableDescription("table", Enumerable.Empty<ColumnDescription>());
            factory.CreateTableDataLoader(table);

            // Second call (should return the ITableDataLoader from cache)
            factory.CreateTableDataLoader(table);

            Assert.AreEqual(1, dataLoaderMock.CreateTableDataLoaderCallCount);
            Assert.AreEqual(1, storeProxy.CachedItemReturnCount);
        }
        public void CachingDataLoaderFactory_MoreTablesMoreQuery()
        {
            var dataLoaderMock = new FakeDataLoader();
            var storeProxy = CreateFakeStoreProxy();

            ITableDataLoaderFactory factory =
                new CachingTableDataLoaderFactory(dataLoaderMock, null, storeProxy);

            // First call
            var table1 = new TableDescription("table1", Enumerable.Empty<ColumnDescription>());
            factory.CreateTableDataLoader(table1);

            // Second call (another table, the cache should not be used)
            var table2 = new TableDescription("table2", Enumerable.Empty<ColumnDescription>());
            factory.CreateTableDataLoader(table2);

            Assert.AreEqual(2, dataLoaderMock.CreateTableDataLoaderCallCount);
            Assert.AreEqual(0, storeProxy.CachedItemReturnCount);
        }
        public void CachingDataLoaderFactory_ReturnsSameData()
        {
            var latchMock = new DataLoaderConfigurationLatchMock();
            var stub = new FakeDataLoader();
            var storeProxy = CreateFakeStoreProxy();
            var table = new TableDescription("table", Enumerable.Empty<ColumnDescription>());

            CachingTableDataLoaderFactory factory =
                new CachingTableDataLoaderFactory(stub, latchMock, storeProxy);

            var data1 = factory.CreateTableDataLoader(table).GetData();

            var data2 = factory.CreateTableDataLoader(table).GetData();

            Enumerable.SequenceEqual(data1, data2);

            // The returned datasets should be exactly the same (same reference)
            Assert.AreEqual(data1, data2);
        }
Ejemplo n.º 12
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="TableDataLoaderBase" /> class.
 /// </summary>
 /// <param name="table"> The metadata of the table. </param>
 public TableDataLoaderBase(TableDescription table)
 {
     this.table = table;
 }
Ejemplo n.º 13
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="TableDataLoaderBase" /> class.
 /// </summary>
 /// <param name="table"> The metadata of the table. </param>
 public TableDataLoaderBase(TableDescription table)
 {
     this.table = table;
 }
Ejemplo n.º 14
0
        /// <summary>
        ///     Loads the table data from the specified table data loader and materializes it
        ///     bases on the specified metadata.
        /// </summary>
        /// <param name="loaderFactory"> The loader factory. </param>
        /// <param name="table"> The table metadata. </param>
        /// <returns> The materialized data. </returns>
        public static IEnumerable <object> Load(
            ITableDataLoaderFactory loaderFactory,
            DbTableInfo table)
        {
            List <ColumnDescription> columns = new List <ColumnDescription>();

            PropertyInfo[]          properties = table.EntityType.GetProperties();
            Func <object, object>[] converters = new Func <object, object> [properties.Length];

            for (int i = 0; i < properties.Length; i++)
            {
                PropertyInfo property = properties[i];
                Type         type     = property.PropertyType;

                // TODO: external
                if (type == typeof(NMemory.Data.Timestamp))
                {
                    converters[i] = ConvertTimestamp;
                    type          = typeof(byte[]);
                }
                else if (type == typeof(NMemory.Data.Binary))
                {
                    converters[i] = ConvertBinary;
                    type          = typeof(byte[]);
                }

                ColumnDescription column = new ColumnDescription(property.Name, type);
                columns.Add(column);
            }

            TableDescription tableDescription =
                new TableDescription(table.TableName.Schema, table.TableName.Name, columns);

            ITableDataLoader loader = loaderFactory.CreateTableDataLoader(tableDescription);

            // Prefetch require info/object to increase performance
            Func <object[], object> initializer = table.EntityInitializer;
            int columnCount = columns.Count;

            // Single array to spare GC
            object[] entityProperties = null;

            foreach (object[] data in loader.GetData())
            {
                if (entityProperties == null)
                {
                    // Initialize at the first element
                    entityProperties = new object[data.Length];
                }

                for (int i = 0; i < columnCount; i++)
                {
                    object propertyValue = data[i];

                    // Use converter if required
                    Func <object, object> converter = converters[i];
                    if (converter != null)
                    {
                        propertyValue = converter.Invoke(propertyValue);
                    }

                    entityProperties[i] = propertyValue;
                }

                yield return(initializer.Invoke(entityProperties));
            }
        }
Ejemplo n.º 15
0
 public ITableDataLoader CreateTableDataLoader(TableDescription table)
 {
     this.CreateTableDataLoaderCallCount++;
     return new FakeTableDataLoader();
 }
Ejemplo n.º 16
0
        /// <summary>
        ///     Loads the table data from the specified table data loader and materializes it
        ///     bases on the specified metadata.
        /// </summary>
        /// <param name="loaderFactory"> The loader factory. </param>
        /// <param name="table"> The table metadata. </param>
        /// <returns> The materialized data. </returns>
        public static IEnumerable<object> Load(
            ITableDataLoaderFactory loaderFactory,
            DbTableInfo table)
        {
            List<ColumnDescription> columns = new List<ColumnDescription>();
            PropertyInfo[] properties = table.EntityType.GetProperties();
            Func<object, object>[] converters = new Func<object,object>[properties.Length];

            for (int i = 0; i < properties.Length; i++)
            {
                PropertyInfo property = properties[i];
                Type type = property.PropertyType;

                // TODO: external
                if (type == typeof(NMemory.Data.Timestamp))
                {
                    converters[i] = ConvertTimestamp;
                    type = typeof(byte[]);
                }
                else if (type == typeof(NMemory.Data.Binary))
                {
                    converters[i] = ConvertBinary;
                    type = typeof(byte[]);
                }

                ColumnDescription column = new ColumnDescription(property.Name, type);
                columns.Add(column);
            }

            TableDescription tableDescription =
                new TableDescription(table.TableName, columns);

            ITableDataLoader loader = loaderFactory.CreateTableDataLoader(tableDescription);

            // Prefetch require info/object to increase performance
            Func<object[], object> initializer = table.EntityInitializer;
            int columnCount = columns.Count;

            // Single array to spare GC
            object[] entityProperties = null;

            foreach (object[] data in loader.GetData())
            {
                if (entityProperties == null)
                {
                    // Initialize at the first element
                    entityProperties = new object[data.Length];
                }

                for (int i = 0; i < columnCount; i++)
                {
                    object propertyValue = data[i];

                    // Use converter if required
                    Func<object, object> converter = converters[i];
                    if (converter != null)
                    {
                        propertyValue = converter.Invoke(propertyValue);
                    }

                    entityProperties[i] = propertyValue;
                }

                yield return initializer.Invoke(entityProperties);
            }
        }
        /// <summary>
        ///     Creates a data loader for the specified table.
        /// </summary>
        /// <param name="table"> The metadata of the table. </param>
        /// <returns>
        ///     The data loader for the table.
        /// </returns>
        public ITableDataLoader CreateTableDataLoader(TableDescription table)
        {
            CachingTableDataLoaderKey key =
                new CachingTableDataLoaderKey(
                    new DataLoaderConfigurationKey(this.wrappedDataLoader),
                    table.Name);

            // If the table data cache does not exists, then the data loader configuration
            // should be locked
            if (latch != null && !this.dataStore.Contains(key))
            {
                // Wait for the lock, this could take some time
                latch.Acquire();

                // Check if the data was created since the waiting
                if (this.dataStore.Contains(key))
                {
                    latch.Release();
                }
            }

            // It does not matter if the table data cache was created during the waiting,
            // maybe there is still tables thats data is not fetched
            return this.dataStore.GetCachedData(key, () => CreateCachedData(table));
        }
        /// <summary>
        ///     Creates a proxy for the global table data cache.
        /// </summary>
        /// <param name="table"> The table metadata. </param>
        /// <returns> The proxy for the cache. </returns>
        private CachingTableDataLoader CreateCachedData(TableDescription table)
        {
            if (this.wrappedTableDataLoaderFactory == null)
            {
                this.wrappedTableDataLoaderFactory =
                    this.wrappedDataLoader.CreateTableDataLoaderFactory();
            }

            ITableDataLoader wrappedTableDataLoader =
                this.wrappedTableDataLoaderFactory.CreateTableDataLoader(table);

            return new CachingTableDataLoader(wrappedTableDataLoader);
        }
 public ITableDataLoader CreateTableDataLoader(TableDescription table)
 {
     return new EntityObjectDataLoaderWrapper(_bindings[table.Name], table.Columns);
 }