Beispiel #1
0
        private static async Task FlushAsync(ShellScope scope, IEnumerable <IndexingTask> tasks)
        {
            var localQueue = new List <IndexingTask>(tasks);

            var serviceProvider = scope.ServiceProvider;

            var session = serviceProvider.GetService <YesSql.ISession>();
            var dbConnectionAccessor = serviceProvider.GetService <IDbConnectionAccessor>();
            var shellSettings        = serviceProvider.GetService <ShellSettings>();
            var logger      = serviceProvider.GetService <ILogger <IndexingTaskManager> >();
            var tablePrefix = shellSettings["TablePrefix"];

            if (!String.IsNullOrEmpty(tablePrefix))
            {
                tablePrefix += '_';
            }

            var contentItemIds = new HashSet <string>();

            // Remove duplicate tasks, only keep the last one
            for (var i = localQueue.Count; i > 0; i--)
            {
                var task = localQueue[i - 1];

                if (contentItemIds.Contains(task.ContentItemId))
                {
                    localQueue.RemoveAt(i - 1);
                }
                else
                {
                    contentItemIds.Add(task.ContentItemId);
                }
            }

            // At this point, content items ids should be unique in localQueue
            var ids   = localQueue.Select(x => x.ContentItemId).ToArray();
            var table = $"{tablePrefix}{nameof(IndexingTask)}";

            using (var connection = dbConnectionAccessor.CreateConnection())
            {
                await connection.OpenAsync();

                using (var transaction = connection.BeginTransaction(session.Store.Configuration.IsolationLevel))
                {
                    var dialect = SqlDialectFactory.For(transaction.Connection);

                    try
                    {
                        if (logger.IsEnabled(LogLevel.Debug))
                        {
                            logger.LogDebug("Updating indexing tasks: {ContentItemIds}", String.Join(", ", tasks.Select(x => x.ContentItemId)));
                        }

                        // Page delete statements to prevent the limits from IN sql statements
                        var pageSize = 100;

                        var deleteCmd = $"delete from {dialect.QuoteForTableName(table)} where {dialect.QuoteForColumnName("ContentItemId")} {dialect.InOperator("@Ids")};";

                        do
                        {
                            var pageOfIds = ids.Take(pageSize).ToArray();

                            if (pageOfIds.Any())
                            {
                                await transaction.Connection.ExecuteAsync(deleteCmd, new { Ids = pageOfIds }, transaction);

                                ids = ids.Skip(pageSize).ToArray();
                            }
                        } while (ids.Any());

                        var insertCmd = $"insert into {dialect.QuoteForTableName(table)} ({dialect.QuoteForColumnName("CreatedUtc")}, {dialect.QuoteForColumnName("ContentItemId")}, {dialect.QuoteForColumnName("Type")}) values (@CreatedUtc, @ContentItemId, @Type);";
                        await transaction.Connection.ExecuteAsync(insertCmd, localQueue, transaction);

                        transaction.Commit();
                    }
                    catch (Exception e)
                    {
                        transaction.Rollback();
                        logger.LogError(e, "An error occurred while updating indexing tasks");

                        throw;
                    }
                }
            }
        }
 public LinearBlockIdGenerator(IConnectionFactory connectionFactory, int range, string tablePrefix)
 {
     _dialect     = SqlDialectFactory.For(connectionFactory.DbConnectionType);
     _range       = range;
     _tablePrefix = tablePrefix;
 }
Beispiel #3
0
        public async Task <IQueryResults> ExecuteQueryAsync(Query query, IDictionary <string, object> parameters)
        {
            var sqlQuery        = query as SqlQuery;
            var sqlQueryResults = new SQLQueryResults();

            var templateContext = new TemplateContext();

            if (parameters != null)
            {
                foreach (var parameter in parameters)
                {
                    templateContext.SetValue(parameter.Key, parameter.Value);
                }
            }

            var tokenizedQuery = await _liquidTemplateManager.RenderAsync(sqlQuery.Template, NullEncoder.Default, templateContext);

            var connection = _dbConnectionAccessor.CreateConnection();
            var dialect    = SqlDialectFactory.For(connection);

            if (!SqlParser.TryParse(tokenizedQuery, dialect, _session.Store.Configuration.TablePrefix, parameters, out var rawQuery, out var messages))
            {
                sqlQueryResults.Items = new object[0];
                connection.Dispose();
                return(sqlQueryResults);
            }

            if (sqlQuery.ReturnDocuments)
            {
                IEnumerable <int> documentIds;

                using (connection)
                {
                    await connection.OpenAsync();

                    using (var transaction = connection.BeginTransaction(_session.Store.Configuration.IsolationLevel))
                    {
                        documentIds = await connection.QueryAsync <int>(rawQuery, parameters, transaction);
                    }
                }

                sqlQueryResults.Items = await _session.GetAsync <ContentItem>(documentIds.ToArray());

                return(sqlQueryResults);
            }
            else
            {
                IEnumerable <dynamic> queryResults;

                using (connection)
                {
                    await connection.OpenAsync();

                    using (var transaction = connection.BeginTransaction(_session.Store.Configuration.IsolationLevel))
                    {
                        queryResults = await connection.QueryAsync(rawQuery, parameters, transaction);
                    }
                }

                var results = new List <JObject>();

                foreach (var document in queryResults)
                {
                    results.Add(JObject.FromObject(document));
                }

                sqlQueryResults.Items = results;
                return(sqlQueryResults);
            }
        }