Created
March 11, 2019 08:39
-
-
Save taosx/8ed09c6cc8319c06a4eba67f29e64f6b to your computer and use it in GitHub Desktop.
How you could improve this code?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let getMigrations: string => array(string) = | |
migrationsPath => Node.Fs.readdirSync(migrationsPath); | |
let readContent: string => string = | |
migrationFilePath => Node.Fs.readFileAsUtf8Sync(migrationFilePath); | |
let handleError = Js.String.make; | |
let countMigrations: | |
Postgres.client => Js.Promise.t(Belt.Result.t(int, Js.Promise.error)) = | |
dbclient => | |
Belt.Result.( | |
Js.Promise.( | |
Postgres.query("SELECT count(*) FROM migrations;", dbclient) | |
|> then_(res => resolve(Ok(int_of_string(res##rows[0]##count)))) | |
|> catch(err => resolve(Error(err))) | |
) | |
); | |
let runMigration = (buf, dbclient) => | |
Postgres.query(buf, dbclient) | |
|> Js.Promise.then_(_ => Js.Promise.resolve(Belt.Result.Ok(dbclient))) | |
|> Js.Promise.catch(err => Js.Promise.resolve(Belt.Result.Error(err))); | |
exception SQL_RECORDING_ERROR(string); | |
let recordMigration = (name, dbclient) => | |
Js.Promise.( | |
Postgres.queryArgs( | |
"INSERT INTO migrations(name) VALUES($1);", | |
[|name|], | |
dbclient, | |
) | |
|> then_(_ => resolve(dbclient)) | |
|> catch(err => reject(SQL_RECORDING_ERROR(Js.String.make(err)))) | |
); | |
exception SQL_SETUP_ERROR(string); | |
let verifyMigrationsTable = dbclient => { | |
open Postgres; | |
open Js.Promise; | |
let createMigrationTableSQL = "CREATE TABLE IF NOT EXISTS migrations ( | |
id UUID PRIMARY KEY DEFAULT uuid_generate_v1mc(), | |
created_at TIMESTAMPTZ NOT NULL DEFAULT now(), | |
name TEXT NOT NULL UNIQUE | |
);"; | |
let createUUIDextensionSQL = "CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";"; | |
let createMigrationTable = () => | |
query(createMigrationTableSQL, dbclient) | |
|> then_(_ => resolve(dbclient)) | |
|> catch(err => reject(SQL_SETUP_ERROR(Js.String.make(err)))); | |
query(createUUIDextensionSQL, dbclient) | |
|> then_(_ => createMigrationTable()) | |
|> catch(err => reject(SQL_SETUP_ERROR(Js.String.make(err)))); | |
}; | |
[@bs.module "path"] external pathResolve: string => string = "resolve"; | |
/* string => Postgres.client => | |
: (string, Postgres.client) => Js.Promise.t(array(unit))*/ | |
exception SQL_MIGRATION_ERROR(string); | |
let runMigrations = (migrationPath, dbclient) => { | |
open Js.Promise; | |
let migrationFolder = pathResolve(Node.Path.join([|migrationPath|])); | |
let migrationFilenames = getMigrations(migrationFolder); | |
dbclient | |
|> verifyMigrationsTable | |
|> then_(_ => countMigrations(dbclient)) | |
|> then_(res => | |
switch (res) { | |
| Belt.Result.Ok(num) => num |> resolve | |
| Belt.Result.Error(err) => | |
raise(SQL_SETUP_ERROR(Js.String.make(err))) | |
} | |
) | |
|> then_(migrationCount => | |
migrationFilenames | |
|> Array.iteri((inx, el) => | |
if (inx >= migrationCount) { | |
readContent(Node.Path.join([|migrationFolder, el|])) | |
|> runMigration(_, dbclient) | |
|> then_(res => | |
switch (res) { | |
| Belt.Result.Ok(client) => | |
client |> recordMigration(el) |> ignore; | |
resolve(); | |
| Belt.Result.Error(err) => | |
Js.log(err); | |
raise(SQL_MIGRATION_ERROR(Js.String.make(err))); | |
} | |
) | |
|> catch(err => { | |
Js.log(err); | |
resolve(); | |
}) | |
|> ignore; | |
} else { | |
(); | |
} | |
) | |
|> resolve | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment