/**
 * Copyright (c) 2018-present, heineiuo.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */ import { path , assert } from "./DBHelper" ; import { FileType } from "./Format" ; import { Env } from "./Env" ; function numberToString ( num ) { let str = String ( num ) ; while ( str . length < 6 ) { str = `0${ str }` ; } return str ; } export function getCurrentFilename ( dbpath ) { return path . resolve ( dbpath , "CURRENT" ) ; } export function getLogFilename ( dbpath , logNumber ) { return path . resolve ( dbpath , `${ numberToString ( logNumber ) }.log` ) ; } export function getTableFilename ( dbpath , tableNumber ) { return path . resolve ( dbpath , `${ numberToString ( tableNumber ) }.ldb` ) ; } export function getManifestFilename ( dbpath , manifestNumber ) { return path . resolve ( dbpath , `MANIFEST-${ numberToString ( manifestNumber ) }` ) ; } export function getLockFilename ( dbpath ) { return path . resolve ( dbpath , `LOCK` ) ; } export function getInfoLogFilename ( dbpath ) { return path . resolve ( dbpath , `LOG` ) ; } export function getOldInfoLogFilename ( dbpath ) { return path . resolve ( dbpath , `LOG.old` ) ; } export function getTempFilename ( dbpath , number ) { assert ( number > 0 ) ; return path . resolve ( dbpath , `${ number }.dbtmp` ) ; } type InternalFile = { isInternalFile : boolean ; filename : string ; number : number ; type : FileType ; } ; export function parseFilename ( filename ) { const internalFile = { isInternalFile : true , } as InternalFile ; if ( filename === "CURRENT" ) { internalFile . number = 0 ; internalFile . type = FileType . kCurrentFile ; } else if ( filename === "LOCK" ) { internalFile . number = 0 ; internalFile . type = FileType . kDBLockFile ; } else if ( filename === "LOG" || filename === "LOG.old" ) { internalFile . number = 0 ; internalFile . type = FileType . kInfoLogFile ; } else if ( filename . startsWith ( "MANIFEST-" ) ) { const num = Number ( filename . substr ( "MANIFEST-" . length ) ) ; if ( isNaN ( num ) ) { internalFile . isInternalFile = false ; return internalFile ; } internalFile . number = num ; internalFile . type = FileType . kDescriptorFile ; } else { const num = Number ( filename . split ( "." ) [ 0 ] ) ; if ( isNaN ( num ) ) { internalFile . isInternalFile = false ; return internalFile ; } const suffix = filename . substr ( filename . split ( "." ) [ 0 ] . length ) ; if ( suffix === ".log" ) { internalFile . type = FileType . kLogFile ; } else if ( suffix === ".ldb" ) { internalFile . type = FileType . kTableFile ; } else if ( suffix === ".dbtmp" ) { internalFile . type = FileType . kTempFile ; } else { internalFile . isInternalFile = false ; return internalFile ; } internalFile . number = num ; } return internalFile ; } export async function setCurrentFile ( env , dbpath , manifestNumber ) { const filename = getManifestFilename ( dbpath , manifestNumber ) ; assert ( filename . startsWith ( path . resolve ( dbpath + "/" ) ) ) ; const content = filename . substr ( path . resolve ( dbpath + "/" ) . length + 1 ) ; const tempFilename = getTempFilename ( dbpath , manifestNumber ) ; let error ; try { await env . writeFile ( tempFilename , content + "\n" ) ; } catch ( e ) { error = e ; } if ( ! error ) { await env . rename ( tempFilename , getCurrentFilename ( dbpath ) ) ; } else { await env . unlink ( tempFilename ) ; } return error ; }