9152d214d2eb86b42b88f1631c929f92e9f2434d — Martin Angers 4 months ago 1427589
implement league archive command
M db/migrations/009_league_teams.sql => db/migrations/009_league_teams.sql +1 -1
@@ 20,6 20,6 @@
   updated   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 
   PRIMARY KEY (id),
-  UNIQUE INDEX ix_league_teams_name (name),
+  UNIQUE INDEX ix_league_teams_league_id_name (league_id, name),
   FOREIGN KEY (league_id) REFERENCES leagues (id) ON DELETE CASCADE
 );

A db/migrations/011_seasons.sql => db/migrations/011_seasons.sql +12 -0
@@ 0,0 1,12 @@
+CREATE TABLE seasons (
+  id        INT UNSIGNED NOT NULL AUTO_INCREMENT,
+  league_id INT UNSIGNED NOT NULL,
+  year      TINYINT UNSIGNED NOT NULL,
+  state     TINYINT UNSIGNED NOT NULL DEFAULT 0, -- 0: unstarted, 1: started, 2: completed
+  created   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+  updated   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+
+  PRIMARY KEY (id),
+  UNIQUE INDEX ix_seasons_league_id_year (league_id, year),
+  FOREIGN KEY (league_id) REFERENCES leagues (id) ON DELETE CASCADE
+);

M src/cmds/league_cmds/archive.js => src/cmds/league_cmds/archive.js +37 -3
@@ 1,9 1,43 @@
+import CFonts from 'cfonts'
+import inquirer from 'inquirer'
+import { DB } from 'mymigrate'
+import { archivableLeagues } from '../../leagues'
+import exec from '../../handlers/league_cmds/archive'
+
 export const command = 'archive'
 export const desc = 'Archive an existing league'
 
 export function builder () {}
 
-export function handler (argv) {
-  console.log ('archive league')
-  console.log (argv)
+function leagueSelectionQuestion (conn) {
+  return () => {
+    return inquirer.prompt ([
+      {
+        type: 'list',
+        name: 'leagueId',
+        message: 'League to archive:',
+        choices () {
+          return archivableLeagues (conn)
+            .then (ls => ls.map (l => { l.value = l.id; return l }))
+        },
+        pageSize: 10,
+      },
+    ])
+  }
+}
+
+export async function handler (argv) {
+  CFonts.say ('Archive League', {
+    font: 'chrome',
+    colors: ['#0ff', 'green', '#ff0'],
+  })
+
+  const conn = await new DB ().connect ()
+  try {
+    const prompt = await leagueSelectionQuestion (conn)
+    const res = await prompt ()
+    await exec (conn, res)
+  } finally {
+    await conn.end ()
+  }
 }

M src/constants.js => src/constants.js +7 -0
@@ 24,9 24,16 @@
   archived: 1,
 })
 
+const SeasonState = Object.freeze ({
+  unstarted: 0,
+  started: 1,
+  completed: 2,
+})
+
 export {
   Constants,
   PlayerName,
   TeamName,
   LeagueState,
+  SeasonState,
 }

A src/handlers/league_cmds/archive.js => src/handlers/league_cmds/archive.js +5 -0
@@ 0,0 1,5 @@
+import { archiveLeague } from '../../leagues'
+
+export default async function (conn, { leagueId }) {
+  await archiveLeague (conn, leagueId)
+}

M src/leagues.js => src/leagues.js +21 -1
@@ 1,4 1,4 @@
-import { LeagueState } from './constants'
+import { LeagueState, SeasonState } from './constants'
 
 // creates a new league and returns the ID
 export async function createLeague (conn, name, state = LeagueState.active) {


@@ 6,6 6,11 @@
   return res.insertId
 }
 
+export async function archiveLeague (conn, leagueId) {
+  await conn.query ('update leagues set state = ? where id = ?',
+    [LeagueState.archived, leagueId])
+}
+
 // returns the list of leagues corresponding to the criteria
 export async function listLeagues (conn, all) {
   let args = []


@@ 19,3 24,18 @@
   const [res] = await conn.query (stmt, args)
   return res
 }
+
+// returns an array of [id, name] of leagues that can be archived.
+export async function archivableLeagues (conn) {
+  const [res] = await conn.query (`
+    select id, name
+    from   leagues l
+    where  state != ?
+    and    not exists (
+      select 1
+      from   seasons s
+      where  s.league_id = l.id
+      and    s.state != ?
+    )`, [LeagueState.archived, SeasonState.completed])
+  return res
+}