private async Task <OperationStatus> IncludeInternal(Guid groupId, Guid userId)
        {
            await using var conn = new NpgsqlConnection(ConnectionString);

            var conflicted = await conn.QuerySingleOrDefaultAsync <Guid?>(
                $@"insert into {PgSchema.GroupMembership} (user_id, group_id)
                       values (@UserId, @GroupId)
                       on conflict (user_id) do update set group_id = {PgSchema.GroupMembership}.group_id
                       returning group_id", new { groupId, userId }).ConfigureAwait(false);

            return(conflicted == null || conflicted.Value == groupId
                ? OperationStatus.Success
                : OperationStatus.Fail(OperationStatusCode.Conflict,
                                       "Студент уже числится в другой академической группе. Сначала исключите его из нее."));
        }
        protected async Task <OperationStatus <T> > Try <T>(Task <OperationStatus <T> > task, string path)
        {
            try
            {
                var sw = Stopwatch.StartNew();

                var status = await task.ConfigureAwait(false);

                sw.Stop();
                Console.WriteLine($"{path} {sw.Elapsed}");
                return(status);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);  // logging
                return(OperationStatus <T> .Fail(OperationStatusCode.InternalServerError));
            }
        }
Exemple #3
0
        public async Task <OperationStatus <Guid> > SignUp(RegistrationData registrationData)
        {
            // TODO
            var profile = new Profile {
                Surname = registrationData.Surname, FirstName = registrationData.FirstName, SecondName = registrationData.SecondName, Group = registrationData.Group
            };
            var authData = new AuthData {
                Email = registrationData.Email, Password = registrationData.Password
            };

            try
            {
                profile.InitAsFresh();

                await using var conn = new NpgsqlConnection(ConnectionString);
                await conn.OpenAsync().ConfigureAwait(false);

                await using var transaction = await conn.BeginTransactionAsync().ConfigureAwait(false);

                await conn.ExecuteAsync(
                    @"insert into auth_data (email, password_hash, user_id)
                          values (@Email, digest(@Password, 'sha256'), @UserId)",
                    new { authData.Email, authData.Password, UserId = profile.Id }).ConfigureAwait(false);

                await conn.ExecuteAsync(
                    @"insert into profile (id, deleted, version, data)
                          values (@Id, false, 0, @Profile::jsonb)", new { profile.Id, profile }).ConfigureAwait(false);

                await transaction.CommitAsync().ConfigureAwait(false);

                return(OperationStatus <Guid> .Success(profile.Id));
            }
            catch (PostgresException e) when(e.SqlState == "23505")
            {
                return(OperationStatus <Guid> .Fail(OperationStatusCode.Conflict, "User with such email already exists"));
            }
            catch (Exception e)
            {
                Console.WriteLine(e);  // TODO logging
                return(OperationStatus <Guid> .Fail(OperationStatusCode.InternalServerError));
            }
        }
Exemple #4
0
        public async Task<OperationStatus> Update(TEntity data)
        {
            try
            {
                await using var conn = new NpgsqlConnection(ConnectionString);

                var version = await conn.QuerySingleOrDefaultAsync<int?>(
                    $@"select version
                          from {relationName}
                          where id = @Id
                            and not deleted
                          limit 1", new {data.Id}).ConfigureAwait(false);

                if (version == null)
                    return OperationStatus.Fail(OperationStatusCode.NotFound);

                if (data.Version != version)
                    return OperationStatus.Fail(OperationStatusCode.Conflict, "Your data version is outdated");

                data.Version = version.Value + 1;

                var updated = await conn.QuerySingleOrDefaultAsync<bool?>(
                    $@"update {relationName}
                          set data = @Data::jsonb,
                              version = version + 1
                          where id = @Id
                            and not deleted
                            and version = @Version
                          returning true", new {data.Id, version, data}).ConfigureAwait(false);
                
                if (updated == null)
                    return OperationStatus.Fail(OperationStatusCode.Conflict, "Your data version is outdated");

                return OperationStatus.Success;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);  // TODO logging
                return OperationStatus.Fail(OperationStatusCode.InternalServerError);
            }
        }
Exemple #5
0
        public async Task<OperationStatus<TEntity>> Read(Guid id)
        {
            try
            {
                await using var conn = new NpgsqlConnection(ConnectionString);
                var data = await conn.QuerySingleOrDefaultAsync<TEntity>(
                    $@"select data
                           from {relationName}
                           where id = @Id
                             and not deleted
                           limit 1", new {id}).ConfigureAwait(false);

                return data != null
                    ? OperationStatus<TEntity>.Success(data)
                    : OperationStatus<TEntity>.Fail(OperationStatusCode.NotFound);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);  // TODO logging
                return OperationStatus<TEntity>.Fail(OperationStatusCode.InternalServerError);
            }
        }
Exemple #6
0
        public async Task<OperationStatus> Delete(Guid id)
        {
            try
            {
                await using var conn = new NpgsqlConnection(ConnectionString);
                var deleted = await conn.QuerySingleOrDefaultAsync<bool?>(
                    $@"update {relationName}
                          set deleted = true
                          where id = @Id
                          returning true", new {id}).ConfigureAwait(false);

                if (deleted == null)
                    return OperationStatus.Fail(OperationStatusCode.NotFound);

                return OperationStatus.Success;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);  // TODO logging
                return OperationStatus.Fail(OperationStatusCode.InternalServerError);
            }
        }
Exemple #7
0
        public async Task<OperationStatus<Guid>> Create(TEntity data)
        {
            try
            {
                data.InitAsFresh();

                await using var conn = new NpgsqlConnection(ConnectionString);
                await conn.ExecuteAsync(
                    $@"insert into {relationName} (id, deleted, version, data)
                           values (@Id, false, 0, @Data::jsonb)", new {data.Id, data}).ConfigureAwait(false);

                return OperationStatus<Guid>.Success(data.Id);
            }
            catch (PostgresException e) when (e.SqlState == "23505")
            {
                return OperationStatus<Guid>.Fail(OperationStatusCode.Conflict, "Entity with such ID already exists");
            }
            catch (Exception e)
            {
                Console.WriteLine(e);  // TODO logging
                return OperationStatus<Guid>.Fail(OperationStatusCode.InternalServerError);
            }
        }