55 This source code is licensed under the BSD-style license found in the
66 LICENSE file in the root directory of this source tree.
77-}
8-
9- {-# LANGUAGE ApplicativeDo #-}
8+ {-# LANGUAGE CPP, ApplicativeDo #-}
109module GleanCLI.Merge (MergeCommand ) where
1110
1211import Control.Exception
@@ -19,10 +18,11 @@ import System.Directory
1918import System.FilePath
2019import System.IO
2120import System.Process
22-
21+ import Data.Text ( unpack )
2322import Control.Concurrent.Stream
2423import Util.OptParse
25- import Util.Log
24+ import Util.Log ( logInfo )
25+ import Glean.Util.ThriftSource (load )
2626import Thrift.Protocol.Compact
2727
2828import Glean.LocalOrRemote (loadDbSchema )
@@ -35,13 +35,23 @@ import Glean.RTS.Foreign.Define (DefineFlags(..), defineBatch)
3535import qualified Glean.RTS.Foreign.Inventory as Inventory
3636import Glean.RTS.Foreign.Ownership
3737import Glean.Database.Schema.Types
38+ import Glean.Database.Util (getDbSchemaFromId )
3839
3940import GleanCLI.Types
4041import GleanCLI.Common (dbOpts , fileFormatOpt , FileFormat (.. ))
4142import Glean.Write (fileToBatches , schemaIdToOpts )
4243import Glean.Write.JSON (buildJsonBatch )
44+ import Glean.Database.Config (schemaSourceIndexConfig )
45+ import Glean.DefaultConfigs (schemaConfigPath )
4346import System.Directory.Extra (listFiles )
4447
48+ #if GLEAN_FACEBOOK
49+ import Configerator (
50+ withConfigeratorAPI ,
51+ defaultConfigeratorOptions ,
52+ )
53+ #endif
54+
4555
4656data MergeCommand = MergeCommand
4757 { mergeFiles :: [FilePath ]
@@ -88,6 +98,9 @@ instance Plugin MergeCommand where
8898 return (schemaInventory dbSchema, Just dbSchema)
8999 Right mergeInventory -> do
90100 inventory <- Inventory. deserialize <$> B. readFile mergeInventory
101+ -- Get the schema_id from the JSON's schema ID field
102+ --- this needs to be done when the file is considered later on
103+ -- dbSchema <-
91104 return (inventory, Nothing )
92105 createDirectoryIfMissing True mergeOutDir
93106 hSetBuffering stderr LineBuffering
@@ -136,21 +149,71 @@ instance Plugin MergeCommand where
136149 let batch = serializeCompact $
137150 batch0 { batch_owned =
138151 ownershipUnits (unionOwnership ownership) }
139- hPutStrLn stderr $ " Writing " <> out <>
140- " (" <> show (B. length batch) <> " )"
152+ logInfo $ " Writing " <> out <>
153+ " (" <> show (B. length batch) <> " bytes )"
141154 B. writeFile out batch
142155
143156 merge fileFormat inventory dbSchema files write = loop 0 0 Nothing files
144157 where
145158 read :: FilePath -> Int -> FactSet -> IO FactOwnership
146159 read file size factSet = do
147160 logInfo $ " Reading " <> file <> " (" <> show size <> " bytes)"
161+ -- Merge can take an existing db or an inventory.
162+ -- A DB has a dbSchema, so we can use that to build the batches
163+ -- to merge
164+ -- An inventory doesn't have a dbSchema, so leads to "Nothing"
165+ -- This means that we need to get the schema from somewhere
166+ --- this will be the first JSON file we see
167+ -- read the 'schema_id' field in that file and create a
168+ -- new dbSchema intance with that using configerator's
169+ -- stored default schema index
170+
148171 batch <- case fileFormat of
149172 JsonFormat -> do
150173 case dbSchema of
151- Nothing -> throwIO $ ErrorCall $
152- " No db schema to serialize json format file. "
153- <> " Please specify the database"
174+ Nothing ->
175+ # if GLEAN_FACEBOOK
176+ withConfigeratorAPI defaultConfigeratorOptions $ \ configAPI ->
177+ -- Load the schema index from the schema directory
178+ let schemaIndexResult =
179+ Right $ schemaSourceIndexConfig schemaConfigPath in do
180+ hPutStrLn stderr $
181+ " Reading current schema index from default "
182+ <> " configerator with path " <> unpack schemaConfigPath
183+
184+ -- Get the schema_id from the JSON file
185+ (batches, Just schema_id) <- fileToBatches file
186+ logInfo(" Schema_ID from JSON file " <> file <> " is "
187+ <> show schema_id)
188+
189+ -- Try to get the DbSchema from the schema ID string
190+ case schemaIndexResult of
191+ Left err -> do
192+ throwIO $ ErrorCall err
193+ Right schemaIndex -> do
194+ logInfo $ " Looking up schema with ID: " <>
195+ show schema_id
196+ -- Materialise the schema index from its Thrift source
197+ concreteIndex <- load configAPI schemaIndex
198+ dbSchemaResult <-
199+ (Right <$>
200+ getDbSchemaFromId (Just concreteIndex) schema_id
201+ )
202+ `catch` \ (e :: SomeException ) ->
203+ return $ Left $ " Failed to get schema: " <> show e
204+
205+ case dbSchemaResult of
206+ Left err -> do
207+ throwIO $ ErrorCall (" Error getting dbSchemaResult"
208+ <> " - exiting. Error is:\n " <> err)
209+ Right dbSchema -> do
210+ logInfo $ " Successfully loaded schema with ID: "
211+ <> show schema_id
212+ buildJsonBatch dbSchema
213+ (schemaIdToOpts $ Just (schemaId dbSchema)) batches
214+ # else
215+ return $ Left $ " Failed to get schema: "
216+ # endif
154217 Just schema -> do
155218 (batches, schema_id_file) <- fileToBatches file
156219 if Just (schemaId schema) == schema_id_file then
@@ -167,7 +230,6 @@ instance Plugin MergeCommand where
167230 buildJsonBatch schema
168231 (schemaIdToOpts $ getSchemaId schema) batches
169232
170-
171233 BinaryFormat -> do
172234 bytes <- B. readFile file
173235 case deserializeCompact bytes of
0 commit comments