Skip to content

Commit

Permalink
Merge pull request #2 from Bennyelg/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
Benny Elgazar committed Sep 12, 2018
2 parents 92dcb5e + 45edbed commit 4fe71ca
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/nimcache/*
csvql
src/nimcache/*
44 changes: 29 additions & 15 deletions src/csvql.nim
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ proc guessCsvDelimiter(filePath: string): char =
else:
return ','


proc appendCsv* (path, alias: string, hasHeader: bool = false): Csv =
## return a new Csv object.

Expand Down Expand Up @@ -114,7 +113,6 @@ proc figureColumnsTypes(rowsSamples: seq[seq[string]]): seq[string] =
let csvTypes = getTypesWithMostProbability(types)
return csvTypes


proc parseCsv* (csv: Csv) =
const numOfSamplingRows = 50
var csvStream = newFileStream(csv.path, fmRead)
Expand Down Expand Up @@ -150,7 +148,6 @@ proc parseCsv* (csv: Csv) =

csv.types = figureColumnsTypes(rowsSampleCount)


proc openConnection* (): Database =
Database(
connection: open(":memory:", nil, nil, nil)
Expand All @@ -168,7 +165,6 @@ proc createTableUsingCsvProperties(db: Database, csv: Csv) =
"""
db.connection.exec(SqlQuery(statement))


proc executeChunk(args: tuple[db: Database, tableName: string, columns: seq[string], rows: seq[seq[string]]]) =
var statement = fmt"""
INSERT INTO {args.tableName}({args.columns.join(",")})
Expand All @@ -181,7 +177,6 @@ proc executeChunk(args: tuple[db: Database, tableName: string, columns: seq[stri
let executableStatement = statement & insertableRows.join(",") & ";"
discard args.db.connection.tryExec(SqlQuery(executableStatement))


proc insertCsvRowsIntoTable(db: Database, csv: Csv) =
db.connection.exec(sql"PRAGMA synchronous=OFF")
db.connection.exec(sql"BEGIN TRANSACTION;")
Expand All @@ -203,7 +198,6 @@ proc insertCsvRowsIntoTable(db: Database, csv: Csv) =

db.connection.exec(sql"COMMIT;")


proc `*`(size: int, del: string): string =
result = "+"
for i in countup(0, size):
Expand Down Expand Up @@ -247,8 +241,18 @@ proc getLongestWordsByPosition(rs: seq[tuple[r: Row, length: int]]): seq[int] =
lengths[idx] = word.len
return lengths

proc exportResults(columns: seq[string], resultSet: seq[seq[string]]): string =
let dt = format(now(), "yyyy-mm-ddHH:mm:ss").replace("-","_").replace(":", "_")
let generatedFilePath = getTempDir() & dt & ".csv"
var fs = newFileStream(generatedFilePath, fmWrite)
for idx, row in resultSet:
if idx == 0:
fs.writeLine(columns.join(","))
fs.writeLine(row.join(","))

return generatedFilePath

proc displayResults(db: Database, csvs: seq[Csv], query: string) =
proc displayResults(db: Database, csvs: seq[Csv], query: string, exportResult: bool = false) =
var queryColumns = getQueryColumns(csvs, query)
var rows: seq[tuple[r: Row, length: int]] = @[]
for row in db.connection.fastRows(SqlQuery(query)):
Expand Down Expand Up @@ -277,11 +281,19 @@ proc displayResults(db: Database, csvs: seq[Csv], query: string) =
for row in fin:
echo("|" & row.join("|") & " |")
echo(row.join("|").len * "-")



if exportResult:
let exportResultHeader = """
----------
::Export::
----------
"""
styledWriteLine(stdout, fgRed, exportResultHeader, resetStyle)
let generatedCsvPath = exportResults(queryColumns, rows.mapIt(it.r))
styledWriteLine(stdout, fgGreen, "File is ready & can be located in: " & generatedCsvPath, resetStyle)

proc parseQuery(query: string): (seq[Csv], string) =
let csvsPaths = re.findAll(query, re"'(.*?)'")
let csvsPaths = re.findAll(query, re"'(.*?).csv'")
var csvs = newSeqOfCap[Csv](csvsPaths.len)
var newQuery = query
let propertiesHeader ="""
Expand All @@ -294,10 +306,12 @@ proc parseQuery(query: string): (seq[Csv], string) =
styledWriteLine(stdout, fgGreen, fmt"t{idx + 1} = {csvPath}", resetStyle)
let csv = appendCsv(csvPath.replace("'", ""), fmt"t{idx + 1}", true)
csvs.add(csv)
newQuery = newQuery.replace(csvPath.replace("'", ""), fmt"t{idx + 1}").replace("'", "")
return (csvs, newQuery)
newQuery = newQuery.replace(csvPath.replace("'", ""), fmt"t{idx + 1}")

proc csvQL(query: string) =
return (csvs, newQuery)

proc csvQL(query: string, exportResult: bool = false) =
let startTime = cpuTime()
let db = openConnection()
let (csvs, adjustedQuery) = parseQuery(query)
Expand All @@ -317,7 +331,7 @@ proc csvQL(query: string) =
::Result::
----------"""
styledWriteLine(stdout, fgRed, queryResultHeader, resetStyle)
displayResults(db, csvs, adjustedQuery)
displayResults(db, csvs, adjustedQuery, exportResult)
styledWriteLine(stdout, fgYellow, fmt"* Total Duration: {cpuTime() - startTime} seconds.", resetStyle)

when isMainModule:
Expand All @@ -326,6 +340,6 @@ when isMainModule:
i.e:
1) SELECT name, day, hour FROM '/path/to/csv/test.csv' as t1 LIMIT 10
2) SELECT name, lastname, birthday FROM '/path/to/csv/test.csv' as t1 LEFT JOIN '/path/to/csv/test2.csv' as t2 ON t1.name = t2.name
""" })
""", "exportResult": "set to true if you want to export the result set." })


0 comments on commit 4fe71ca

Please sign in to comment.