示例#1
0
        private static IRouteResponse SaveLogEntry(AuditLog entry)
        {
            using (var conn = OpenConnection())
            {
                CreateLogEntry(conn, entry);
            }

            return(RouteResponse.OK());
        }
示例#2
0
        private static IRouteResponse BeginTransaction(RequestCommon req)
        {
            var conn        = OpenConnection();
            var transaction = conn.BeginTransaction();

            transactions[req.UserId] = new Transaction(transaction, conn);

            return(RouteResponse.OK());
        }
示例#3
0
        private static IRouteResponse ImportEntity(EntityData entity)
        {
            IRouteResponse resp = RouteResponse.OK();

            // Evil!
            // Lock the whole process in case another async call fails and the client calls abort which gets
            // processed and then more import calls are received.
            lock (schemaLocker)
            {
                // We assume there's data!
                using (var tconn = OpenConnection())
                {
                    CheckForTable(tconn, entity.StoreName);

                    // Somewhat annoyingly we actually have to check all the records for any new field.
                    entity.StoreData.ForEach(d =>
                    {
                        foreach (var prop in d.Properties())
                        {
                            CheckForField(tconn, entity.StoreName, prop.Name);
                        }
                    });
                }
            }

            var tinfo       = transactions[entity.UserId];
            var transaction = tinfo.t;
            var conn        = tinfo.c;

            try
            {
                Interlocked.Increment(ref tinfo.transactionCount);
                Console.WriteLine($"{tinfo.transactionCount} {tinfo.rollbackCount} {tinfo.c.State}");

                for (int n = 0; n < entity.StoreData.Count && Interlocked.Read(ref tinfo.rollbackCount) == 0; ++n)
                {
                    lock (schemaLocker)
                    {
                        InsertRecord(conn, transaction, entity.UserId, entity.StoreName, entity.StoreData[n]);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                resp = RouteResponse.ServerError(new { Error = ex.Message });
            }
            finally
            {
                Interlocked.Decrement(ref tinfo.transactionCount);
            }


            return(resp);
        }
示例#4
0
        private static IRouteResponse Load(LoadStore store)
        {
            Console.WriteLine($"Load store {store.StoreName} for user {store.UserId}");

            using (var conn = OpenConnection())
            {
                CheckForTable(conn, store.StoreName);
                var data = LoadStore(conn, store.StoreName, store.UserId);

                return(RouteResponse.OK(data));
            }
        }
示例#5
0
        private static IRouteResponse CommitTransaction(RequestCommon req)
        {
            Console.WriteLine("Committing transactions...");
            var tinfo = transactions[req.UserId];

            Console.WriteLine($"{tinfo.transactionCount} {tinfo.rollbackCount} {tinfo.c.State}");
            tinfo.t.Commit();
            tinfo.c.Close();
            transactions.Remove(req.UserId, out _);

            return(RouteResponse.OK());
        }
示例#6
0
        private static IRouteResponse ImportAuditLog(AuditLogEntries log)
        {
            using (var conn = OpenConnection())
            {
                // Evil!
                lock (schemaLocker)
                {
                    UpdateSchema(conn, log.Entries);

                    // The CRUD operations have to be in the lock operation so that another request doesn't update the schema while we're updating the record.
                    log.Entries.ForEach(l => PersistTransaction(conn, l, log.UserId));
                }
            }

            return(RouteResponse.OK());
        }
示例#7
0
        private static IRouteResponse Save(SaveStore store)
        {
            var logs = JsonConvert.DeserializeObject <List <AuditLog> >(store.AuditLog);

            using (var conn = OpenConnection())
            {
                // Evil!
                lock (schemaLocker)
                {
                    UpdateSchema(conn, logs);

                    // The CRUD operations have to be in the lock operation so that another request doesn't update the schema while we're updating the record.
                    logs.ForEach(l => PersistTransaction(conn, l, store.UserId));
                }
            }

            return(RouteResponse.OK());
        }
示例#8
0
        private static IRouteResponse RollbackTransaction(RequestCommon req)
        {
            var tinfo = transactions[req.UserId];

            Interlocked.Increment(ref tinfo.rollbackCount);

            while (Interlocked.Read(ref tinfo.transactionCount) > 0)
            {
                // Thread.Sleep(0) is evil, see some article I wrote somewhere regarding that.
                Thread.Sleep(1);
            }

            Console.WriteLine($"Abort {req.UserId}");
            transactions[req.UserId].t.Rollback();
            transactions[req.UserId].c.Close();
            transactions.Remove(req.UserId, out _);
            // No need to decrement the rollback counter as we're all done.

            return(RouteResponse.OK());
        }