1 | 'use strict'
|
2 |
|
3 | const fs = require('fs')
|
4 | const path = require('path')
|
5 | const getColumnNames = require('./get-column-names')
|
6 | const upath = require('upath')
|
7 | const debug = require('debug')('supercopy')
|
8 | const promisify = require('util').promisify
|
9 |
|
10 | const readdirAsync = promisify(fs.readdir)
|
11 | const lstatAsync = promisify(fs.lstat)
|
12 | const columnNamesAsync = promisify(getColumnNames)
|
13 |
|
14 | module.exports = collect
|
15 |
|
16 | async function collect (options) {
|
17 | const info = {}
|
18 | if (Object.prototype.hasOwnProperty.call(options, 'truncateTables') && options.truncateTables === true) {
|
19 | if (Object.prototype.hasOwnProperty.call(options, 'topDownTableOrder') && options.topDownTableOrder.length !== 0) {
|
20 | info.truncateTables = options.topDownTableOrder.slice(0)
|
21 | info.truncateTables.reverse()
|
22 | debug(info)
|
23 | } else {
|
24 | debug('WARNING: truncateTables is set to true, but topDownTableOrder has not been specified (or is empty) (so truncation will not be carried out)')
|
25 | }
|
26 | }
|
27 |
|
28 | const rootDir = options.sourceDir
|
29 | debug(`Starting to collect file info for ${rootDir}`)
|
30 |
|
31 | const dirs = await directoriesUnder(rootDir)
|
32 | for (const dirPath of dirs) {
|
33 | debug(`+ ./${path.basename(dirPath)}:`)
|
34 |
|
35 | const action = { }
|
36 | info[path.basename(dirPath)] = action
|
37 |
|
38 | for (const [filePath, size] of await filesUnder(dirPath)) {
|
39 | const fileName = path.basename(filePath)
|
40 | debug(`+ ./${fileName}:`)
|
41 |
|
42 | try {
|
43 | const columnNames = await columnNamesAsync(filePath, options)
|
44 | action[upath.normalize(filePath)] = {
|
45 | tableName: path.basename(filePath, path.extname(filePath)),
|
46 | columnNames: columnNames,
|
47 | size: size
|
48 | }
|
49 | } catch (err) {
|
50 | debug(` Could not get column names for ${fileName}`)
|
51 | }
|
52 | }
|
53 | }
|
54 |
|
55 | return info
|
56 | }
|
57 |
|
58 | function directoriesUnder (rootDir) {
|
59 | return directoryContents(
|
60 | rootDir,
|
61 | stats => stats.isDirectory(),
|
62 | (path, stats) => path
|
63 | )
|
64 | }
|
65 |
|
66 | function filesUnder (rootDir) {
|
67 | return directoryContents(
|
68 | rootDir,
|
69 | stats => (stats.isFile() && stats.size !== 0),
|
70 | (path, stats) => [path, stats.size]
|
71 | )
|
72 | }
|
73 |
|
74 | async function directoryContents (rootDir, filter, transform) {
|
75 | const items = await readdirAsync(rootDir)
|
76 | debug(`Directory contents [${items}]`)
|
77 | const statedItems = await Promise.all(
|
78 | items.map(async item => {
|
79 | const itemPath = path.join(rootDir, item)
|
80 | const stats = await lstatAsync(itemPath)
|
81 | return filter(stats) ? transform(itemPath, stats) : null
|
82 | })
|
83 | )
|
84 | const dirs = statedItems.filter(d => !!d)
|
85 | return dirs
|
86 | }
|