import { Effect, Context } from "effect";
import postgres from "postgres";
const dbConn = postgres("postgres://postgres:postgres@localhost:5432/demo");
const IDbConn = Context.Tag<postgres.Sql>();
async function createUserInDb(conn: postgres.Sql) {
// could throw an error if a constraint is violated
await conn`INSERT INTO users (name) VALUES ('John')`
return "user created"
}
async function createUserProfileInDb(conn: postgres.Sql) {
// could throw an error if the user does not exist or some other constraint is violated
await conn`INSERT INTO user_profiles (user_id, bio) VALUES (1, 'I am John')`
return "user profile created"
}
function createUser() {
return IDbConn.pipe(
Effect.tryMapPromise({
try: async (conn) => await createUserInDb(conn),
catch: (error) => {
if (error instanceof Error) {
return error;
}
return new Error(`unknown error: ${error}`);
},
})
)
}
function createUserProfile() {
return IDbConn.pipe(
Effect.tryMapPromise({
try: async (conn) => await createUserProfileInDb(conn),
catch: (error) => {
if (error instanceof Error) {
return error;
}
return new Error(`unknown error: ${error}`);
},
})
)
}
async function withoutTransaction() {
return Effect.gen(function* (_) {
const user = yield* _(createUser());
const userProfile = yield* _(createUserProfile());
return { user, userProfile };
}).pipe(
Effect.provideService(IDbConn, dbConn),
Effect.runPromise,
);
}
async function withTransaction() {
// how to use effects with `postgres` transactions
return Effect.gen(function* (_) {
const conn = yield* _(IDbConn);
return conn.begin(async (sql) => {
const user = yield* _(createUser());
const userProfile = yield* _(createUserProfile());
return { user, userProfile };
});
}).pipe(
Effect.provideService(IDbConn, dbConn),
Effect.runPromise,
);
}
import { Effect, Context } from "effect";
import postgres from "postgres";
const dbConn = postgres("postgres://postgres:postgres@localhost:5432/demo");
const IDbConn = Context.Tag<postgres.Sql>();
async function createUserInDb(conn: postgres.Sql) {
// could throw an error if a constraint is violated
await conn`INSERT INTO users (name) VALUES ('John')`
return "user created"
}
async function createUserProfileInDb(conn: postgres.Sql) {
// could throw an error if the user does not exist or some other constraint is violated
await conn`INSERT INTO user_profiles (user_id, bio) VALUES (1, 'I am John')`
return "user profile created"
}
function createUser() {
return IDbConn.pipe(
Effect.tryMapPromise({
try: async (conn) => await createUserInDb(conn),
catch: (error) => {
if (error instanceof Error) {
return error;
}
return new Error(`unknown error: ${error}`);
},
})
)
}
function createUserProfile() {
return IDbConn.pipe(
Effect.tryMapPromise({
try: async (conn) => await createUserProfileInDb(conn),
catch: (error) => {
if (error instanceof Error) {
return error;
}
return new Error(`unknown error: ${error}`);
},
})
)
}
async function withoutTransaction() {
return Effect.gen(function* (_) {
const user = yield* _(createUser());
const userProfile = yield* _(createUserProfile());
return { user, userProfile };
}).pipe(
Effect.provideService(IDbConn, dbConn),
Effect.runPromise,
);
}
async function withTransaction() {
// how to use effects with `postgres` transactions
return Effect.gen(function* (_) {
const conn = yield* _(IDbConn);
return conn.begin(async (sql) => {
const user = yield* _(createUser());
const userProfile = yield* _(createUserProfile());
return { user, userProfile };
});
}).pipe(
Effect.provideService(IDbConn, dbConn),
Effect.runPromise,
);
}