{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}

module Unison.Codebase.SqliteCodebase.Migrations.MigrateSchema11To12 (migrateSchema11To12) where

import U.Codebase.Sqlite.Queries qualified as Queries
import Unison.Debug qualified as Debug
import Unison.Sqlite qualified as Sqlite
import Prelude hiding (log)

-- | This migration just deletes all the old name lookups, it doesn't recreate them.
-- On share we'll rebuild only the required name lookups from scratch.
migrateSchema11To12 :: Sqlite.Transaction ()
migrateSchema11To12 :: Transaction ()
migrateSchema11To12 = do
  SchemaVersion -> Transaction ()
Queries.expectSchemaVersion SchemaVersion
11
  Transaction ()
dropOldNameLookupTables
  Transaction ()
deleteAllNameLookups
  DebugFlag -> String -> Transaction ()
forall (m :: * -> *). Monad m => DebugFlag -> String -> m ()
Debug.debugLogM DebugFlag
Debug.Migration String
"Adding name lookup mount tables"
  Transaction ()
Queries.addNameLookupMountTables
  SchemaVersion -> Transaction ()
Queries.setSchemaVersion SchemaVersion
12

-- | These are old name lookups from before we switched to a branch-hash keyed
-- approach. It can be dropped now to reclaim space.
dropOldNameLookupTables :: Sqlite.Transaction ()
dropOldNameLookupTables :: Transaction ()
dropOldNameLookupTables = do
  DebugFlag -> String -> Transaction ()
forall (m :: * -> *). Monad m => DebugFlag -> String -> m ()
Debug.debugLogM DebugFlag
Debug.Migration String
"Dropping old name lookup tables"
  HasCallStack => Sql -> Transaction ()
Sql -> Transaction ()
Sqlite.execute
    [Sqlite.sql|
      DROP TABLE IF EXISTS term_name_lookup
    |]
  HasCallStack => Sql -> Transaction ()
Sql -> Transaction ()
Sqlite.execute
    [Sqlite.sql|
      DROP TABLE IF EXISTS type_name_lookup
    |]

-- | This migration truncates the scoped name lookup tables, then Share will rebuild
-- the living name lookups from scratch because it's faster, safer, and simpler to do it that
-- way.
deleteAllNameLookups :: Sqlite.Transaction ()
deleteAllNameLookups :: Transaction ()
deleteAllNameLookups = do
  DebugFlag -> String -> Transaction ()
forall (m :: * -> *). Monad m => DebugFlag -> String -> m ()
Debug.debugLogM DebugFlag
Debug.Migration String
"Deleting all name lookups"
  -- Bare deletes are optimized into table truncations by sqlite
  HasCallStack => Sql -> Transaction ()
Sql -> Transaction ()
Sqlite.execute
    [Sqlite.sql|
      DELETE FROM scoped_term_name_lookup
    |]
  HasCallStack => Sql -> Transaction ()
Sql -> Transaction ()
Sqlite.execute
    [Sqlite.sql|
      DELETE FROM scoped_type_name_lookup
    |]
  HasCallStack => Sql -> Transaction ()
Sql -> Transaction ()
Sqlite.execute
    [Sqlite.sql|
      DELETE FROM name_lookups
    |]