Skip to content

Commit 25cbc3e

Browse files
committed
Refactoring
1 parent b24ff44 commit 25cbc3e

3 files changed

Lines changed: 115 additions & 85 deletions

File tree

glean/db/Glean/Database/Config.hs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,41 @@
88

99
{-# LANGUAGE ApplicativeDo, CPP #-}
1010
module Glean.Database.Config (
11+
-- * DataStore
1112
DataStore(..),
1213
fileDataStore,
1314
tmpDataStore,
1415
memoryDataStore,
16+
17+
-- * Config, and options parser
18+
options,
1519
Config(..),
20+
DebugFlags(..),
21+
22+
-- * Finding and parsing the schema
1623
ServerConfig.SchemaLocation(..),
1724
showSchemaLocation,
1825
schemaLocation,
1926
schemaLocationOption,
20-
DebugFlags(..),
21-
options,
2227
processSchema,
2328
processSchemaCached,
2429
processOneSchema,
2530
SchemaIndex(..),
2631
schemaForSchemaId,
2732
ProcessedSchema(..),
28-
schemaSourceIndexConfig,
2933
catSchemaFiles,
3034
schemaLocationToSource,
31-
schemaLocationFiles,
32-
schemaSourceFilesFromDir,
33-
schemaSourceDir,
34-
schemaSourceFile,
35-
schemaSourceIndexFile,
3635
parseSchemaDir,
3736
parseSchemaIndex,
38-
-- testing
37+
loadSchemaIndex,
38+
39+
-- * Testing only
40+
41+
-- if you're using these somewhere other than a test,
42+
-- you should probably be using something from the API above instead.
3943
processSchemaForTesting,
44+
schemaLocationFiles,
45+
schemaSourceDir,
4046
) where
4147

4248
import Control.Exception
@@ -426,6 +432,16 @@ schemaLocation cfg server_cfg = do
426432
other ->
427433
return other
428434

435+
-- | Find and load the SchemaIndex, taking into account command line
436+
-- flags, the ServerConfig, and the cfgSchemaHook. This is a
437+
-- convenience function used by the CLI.
438+
loadSchemaIndex :: ConfigProvider c => Config -> c -> IO SchemaIndex
439+
loadSchemaIndex cfg cfgAPI = do
440+
serverConfig <- ThriftSource.load cfgAPI (cfgServerConfig cfg)
441+
loc <- schemaLocation cfg serverConfig
442+
let (schemaSource, _) = cfgSchemaHook cfg loc
443+
ThriftSource.load cfgAPI schemaSource
444+
429445
showSchemaLocation :: ServerConfig.SchemaLocation -> String
430446
showSchemaLocation = \case
431447
ServerConfig.SchemaLocation_dir d -> "dir:" <> Text.unpack d

glean/tools/gleancli/GleanCLI.hs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ import qualified Glean.Types as Thrift
5050
import Glean.Impl.ConfigProvider
5151
import Glean.Util.ConfigProvider
5252
import Glean.Util.ShellPrint
53-
import qualified Glean.Util.ThriftSource as ThriftSource
5453
import Glean.Shell
5554

5655
import GleanCLI.Backup
@@ -661,11 +660,9 @@ instance Plugin WriteSerializedInventoryCommand where
661660
let cfg = case svc of
662661
Glean.Local cfg _ -> cfg
663662
Glean.Remote{} -> def
664-
serverConfig <- ThriftSource.load cfgAPI (cfgServerConfig cfg)
665-
loc <- GleanDB.schemaLocation cfg serverConfig
666-
let (schemaSource, _) = GleanDB.cfgSchemaHook cfg loc
667-
index <- ThriftSource.load cfgAPI schemaSource
668-
dbSchema <- newDbSchema Nothing index selector readWriteContent def
663+
index <- GleanDB.loadSchemaIndex cfg cfgAPI
664+
dbSchema <- newDbSchema Nothing index selector
665+
readWriteContent def
669666
return $ Inventory.serialize $ schemaInventory dbSchema
670667

671668
inventory <- case writeSerializedInventoryFrom of

glean/tools/gleancli/GleanCLI/Merge.hs

Lines changed: 87 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import Util.OptParse
2525
import Util.Log ( logInfo )
2626
import Thrift.Protocol.Compact
2727

28+
import qualified Glean.Database.Config as GleanDB
29+
import Glean.Database.Schema
30+
import Glean.Database.Schema.Types
2831
import Glean.LocalOrRemote (loadDbSchema)
2932
import qualified Glean.LocalOrRemote as Glean
3033
import Glean.Types
@@ -34,11 +37,6 @@ import qualified Glean.RTS.Foreign.FactSet as FactSet
3437
import Glean.RTS.Foreign.Define (DefineFlags(..), defineBatch)
3538
import qualified Glean.RTS.Foreign.Inventory as Inventory
3639
import Glean.RTS.Foreign.Ownership
37-
import qualified Glean.Database.Config as GleanDB
38-
import Glean.Database.Schema.Types
39-
import qualified Glean.Util.ThriftSource as ThriftSource
40-
import Glean.Database.Config (cfgServerConfig)
41-
import Glean.Database.Schema
4240

4341
import GleanCLI.Types
4442
import GleanCLI.Common (dbOpts, fileFormatOpt, FileFormat (..))
@@ -51,7 +49,7 @@ data MergeCommand = MergeCommand
5149
, mergeFileSize :: Int
5250
, mergeOutDir :: FilePath
5351
, fileFormat :: FileFormat
54-
, inventorySource :: Either Repo FilePath
52+
, inventorySource :: Maybe (Either Repo FilePath)
5553
}
5654

5755
inventoryOpt :: Parser FilePath
@@ -61,6 +59,11 @@ inventoryOpt = strOption $
6159
help ("Inventory created with --write-serialized-inventory and which "
6260
<> "was used to create binary format files of facts")
6361

62+
data SchemaData
63+
= HaveSchema DbSchema
64+
| HaveInventory Inventory.Inventory
65+
| HaveNothing
66+
6467
instance Plugin MergeCommand where
6568
parseCommand = commandParser "merge" (progDesc "Merge fact files") $ do
6669
mergeFiles <- many $ strArgument (
@@ -77,29 +80,40 @@ instance Plugin MergeCommand where
7780
long "output" <>
7881
metavar "DIR" <>
7982
help "Destination directory for the merged fact files"
80-
inventorySource <- Left <$> dbOpts <|> Right <$> inventoryOpt
83+
inventorySource <- optional $ Left <$> dbOpts <|> Right <$> inventoryOpt
8184
fileFormat <- fileFormatOpt BinaryFormat
8285
return MergeCommand{..}
8386

8487
withService evb cfgAPI svc MergeCommand{..} = do
85-
(inventory, dbSchema) <- case inventorySource of
86-
Left repo -> do
88+
-- * --file-format=binary requires an inventory, from either --db or
89+
-- --inventory.
90+
-- * --file-format=json requires a dbSchema, from either --db or
91+
-- schema_id in the JSON file. It's pointless to use --inventory with
92+
-- --file-format=json, because the inventory isn't used.
93+
schemaData <- case inventorySource of
94+
Just (Left repo) -> do
8795
dbSchema <- Glean.withBackendWithDefaultOptions
8896
evb cfgAPI svc Nothing $ \backend -> do
8997
loadDbSchema backend repo
90-
logInfo("db's schema ID is: " <> show(schemaId dbSchema))
91-
return (schemaInventory dbSchema, Just dbSchema)
92-
Right mergeInventory -> do
93-
inventory <- Inventory.deserialize <$> B.readFile mergeInventory
94-
-- Get the schema_id from the JSON's schema ID field
95-
--- this needs to be done when the file is considered later on
96-
-- dbSchema <-
97-
return (inventory, Nothing)
98+
logInfo("db's schema ID is: " <> show (schemaId dbSchema))
99+
return (HaveSchema dbSchema)
100+
Just (Right mergeInventory) -> do
101+
case fileFormat of
102+
JsonFormat -> do
103+
hPutStrLn stderr $
104+
"Warning: --inventory is ignored with --file-format=json"
105+
return HaveNothing
106+
_ -> do
107+
inventory <- Inventory.deserialize <$> B.readFile mergeInventory
108+
return (HaveInventory inventory)
109+
Nothing ->
110+
return HaveNothing
98111
createDirectoryIfMissing True mergeOutDir
99112
hSetBuffering stderr LineBuffering
100113
outputs <- newIORef []
101114
expandedMergeFiles <- mapM expandFile mergeFiles
102-
stream 1 (merge fileFormat inventory dbSchema $ concat expandedMergeFiles)
115+
stream 1
116+
(merge fileFormat schemaData (concat expandedMergeFiles))
103117
(writeToFile outputs)
104118
-- stream overlaps writing with reading
105119
files <- readIORef outputs
@@ -146,84 +160,87 @@ instance Plugin MergeCommand where
146160
" (" <> show (B.length batch) <> " bytes)"
147161
B.writeFile out batch
148162

149-
merge fileFormat inventory dbSchema files write = loop 0 0 Nothing files
163+
merge fileFormat schemaData files write =
164+
loop 0 0 Nothing schemaData files
150165
where
151-
read :: FilePath -> Int -> FactSet -> IO FactOwnership
152-
read file size factSet = do
166+
read
167+
:: FilePath
168+
-> Int
169+
-> FactSet
170+
-> SchemaData
171+
-> IO (FactOwnership, SchemaData)
172+
read file size factSet schemaData = do
153173
logInfo $ "Reading " <> file <> " (" <> show size <> " bytes)"
154-
-- Merge can take an existing db or an inventory.
155-
-- A DB has a dbSchema, so we can use that to build the batches
156-
-- to merge
157-
-- An inventory doesn't have a dbSchema, so leads to "Nothing"
158-
-- This means that we need to get the schema from somewhere
159-
--- this will be the first JSON file we see
160-
-- read the 'schema_id' field in that file and create a
161-
-- new dbSchema intance with that using configerator's
162-
-- stored default schema index
163-
164-
batch <- case fileFormat of
174+
175+
let
176+
define batch inventory newSchemaData = do
177+
subst <- defineBatch factSet inventory batch
178+
DefineFlags {
179+
trustRefs = True,
180+
ignoreRedef = True }
181+
own <- substOwnership subst $ FactOwnership (batch_owned batch)
182+
return (own, newSchemaData)
183+
184+
case fileFormat of
165185
JsonFormat -> do
166186
(batches, schema_id_file) <- fileToBatches file
167-
case dbSchema of
168-
Nothing -> do
187+
dbSchema <- case schemaData of
188+
HaveSchema dbSchema
189+
| Just schema_id <- schema_id_file,
190+
schema_id /= schemaId dbSchema ->
191+
throwIO $ ErrorCall $
192+
"Schema ID mismatch:\ndb: "
193+
<> show (schemaId dbSchema) <> "\nvs\nFile: "
194+
<> file <> " has " <> show schema_id
195+
| otherwise -> return dbSchema
196+
_otherwise -> do
197+
-- the first time (only), we load the schema we'll
198+
-- be using to parse the JSON files.
169199
schema_id <- case schema_id_file of
170-
Nothing -> throwIO $ ErrorCall "missing schema ID"
200+
Nothing -> throwIO $ ErrorCall $
201+
file <> ": missing schema_id"
171202
Just id -> return id
172203
let cfg = case svc of
173204
Glean.Local cfg _ -> cfg
174205
Glean.Remote{} -> def
175-
serverConfig <- ThriftSource.load cfgAPI (cfgServerConfig cfg)
176-
loc <- GleanDB.schemaLocation cfg serverConfig
177-
let (schemaSource, _) = GleanDB.cfgSchemaHook cfg loc
178-
index <- ThriftSource.load cfgAPI schemaSource
179-
dbSchema <- newDbSchema Nothing index
180-
(SpecificSchemaId schema_id) readWriteContent def
181-
buildJsonBatch dbSchema
182-
(schemaIdToOpts $ Just (schemaId dbSchema)) batches
183-
Just schema -> do
184-
if Just(schemaId schema) == schema_id_file then
185-
logInfo(
186-
"Schema matches with db schema. Merging data from "
187-
<> file
188-
)
189-
else
190-
throwIO $ ErrorCall $
191-
"ERROR - ABORTING MERGE\nSchema ID mismatch:\ndb: "
192-
<> show (schemaId schema) <> "\nvs\nFile: "
193-
<> file <> " has " <> show schema_id_file
194-
let getSchemaId theschema = Just(schemaId theschema) in
195-
buildJsonBatch schema
196-
(schemaIdToOpts $ getSchemaId schema) batches
206+
index <- GleanDB.loadSchemaIndex cfg cfgAPI
207+
newDbSchema Nothing index (SpecificSchemaId schema_id)
208+
readWriteContent def
209+
batch <- buildJsonBatch dbSchema
210+
(schemaIdToOpts $ Just (schemaId dbSchema)) batches
211+
define batch (schemaInventory dbSchema) (HaveSchema dbSchema)
197212

198213
BinaryFormat -> do
214+
inventory <- case schemaData of
215+
HaveSchema dbSchema -> return (schemaInventory dbSchema)
216+
HaveInventory inventory -> return inventory
217+
HaveNothing -> throwIO $ ErrorCall $
218+
"--file-format=binary requires either --inventory, " <>
219+
"--db, or --db-name and --db-instance"
199220
bytes <- B.readFile file
200221
case deserializeCompact bytes of
201222
Left err -> throwIO $ ErrorCall $
202223
"failed to deserialize " <> file <> ": " <> err
203-
Right batch -> return batch
204-
subst <- defineBatch factSet inventory batch
205-
DefineFlags {
206-
trustRefs = True,
207-
ignoreRedef = True }
208-
substOwnership subst $ FactOwnership (batch_owned batch)
209-
210-
loop !_ _ Nothing [] = return ()
211-
loop !n _ (Just set) [] = write (n, Right set)
212-
loop !n currentSize acc (f : files) = do
224+
Right batch ->
225+
define batch inventory (HaveInventory inventory)
226+
227+
loop !_ _ Nothing _ [] = return ()
228+
loop !n _ (Just set) _ [] = write (n, Right set)
229+
loop !n currentSize acc schema (f : files) = do
213230
size <- fromIntegral <$> getFileSize f
214231
if size > mergeFileSize && fileFormat == BinaryFormat
215232
-- just copy huge binary files
216233
then do
217234
write (n, Left f)
218-
loop (n+1) currentSize acc files
235+
loop (n+1) currentSize acc schema files
219236
else do
220237
(factSet, ownership) <- case acc of
221238
Nothing -> (,[]) <$> FactSet.new lowestFid
222239
Just facts -> return facts
223-
owners <- read f size factSet
240+
(owners, schema) <- read f size factSet schema
224241
newSize <- factSetSize factSet
225242
let facts = (factSet, owners : ownership)
226243
(n, acc) <- if newSize > mergeFileSize
227244
then do write (n, Right facts); return (n+1, Nothing)
228245
else return (n, Just facts)
229-
loop n newSize acc files
246+
loop n newSize acc schema files

0 commit comments

Comments
 (0)