248 lines
6.9 KiB
Text
248 lines
6.9 KiB
Text
#include once "sqlite3.bi"
|
|
#include once "string.bi"
|
|
#include once "crt.bi"
|
|
|
|
' Callback para SQLite
|
|
Function callback Cdecl (Byval NotUsed As Any Ptr, Byval argc As Integer, _
|
|
Byval argv As ZString Ptr Ptr, Byval colName As ZString Ptr Ptr) As Integer
|
|
|
|
For i As Integer = 0 To argc - 1
|
|
If argv[i] <> NULL Then
|
|
Print *colName[i] & ": " & *argv[i] & " ";
|
|
Else
|
|
Print *colName[i] & ": NULL ";
|
|
End If
|
|
Next
|
|
Print
|
|
|
|
Return 0
|
|
End Function
|
|
|
|
Sub createCSVfiles()
|
|
Dim As Integer ff
|
|
|
|
If Dir("patients.csv") = "" Then
|
|
ff = Freefile
|
|
Open "patients.csv" For Output As #ff
|
|
Print #ff, "PATIENT_ID,LASTNAME"
|
|
Print #ff, "1001,Hopper"
|
|
Print #ff, "4004,Wirth"
|
|
Print #ff, "3003,Kemeny"
|
|
Print #ff, "2002,Gosling"
|
|
Print #ff, "5005,Kurtz"
|
|
Close #ff
|
|
End If
|
|
|
|
If Dir("visits.csv") = "" Then
|
|
ff = Freefile
|
|
Open "visits.csv" For Output As #ff
|
|
Print #ff, "PATIENT_ID,VISIT_DATE,SCORE"
|
|
Print #ff, "2002,2020-09-10,6.8"
|
|
Print #ff, "1001,2020-09-17,5.5"
|
|
Print #ff, "4004,2020-09-24,8.4"
|
|
Print #ff, "2002,2020-10-08,"
|
|
Print #ff, "1001,,6.6"
|
|
Print #ff, "3003,2020-11-12,"
|
|
Print #ff, "4004,2020-11-05,7.0"
|
|
Print #ff, "1001,2020-11-19,5.3"
|
|
Close #ff
|
|
End If
|
|
End Sub
|
|
|
|
Sub createTableHeaders(db As sqlite3 Ptr)
|
|
Dim As ZString Ptr errMsg = NULL
|
|
|
|
' Create the patient and visit table
|
|
sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS patients (PATIENT_ID INT, LASTNAME TEXT);", Cast(Any Ptr, @callback), NULL, @errMsg)
|
|
If errMsg <> NULL Then
|
|
Print "Error creating patients table: " & *errMsg
|
|
sqlite3_free(errMsg)
|
|
End If
|
|
|
|
sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS visits (PATIENT_ID INT, VISIT_DATE TEXT, SCORE NUMERIC(4,1));", Cast(Any Ptr, @callback), NULL, @errMsg)
|
|
If errMsg <> NULL Then
|
|
Print "Error creating visits table: " & *errMsg
|
|
sqlite3_free(errMsg)
|
|
End If
|
|
End Sub
|
|
|
|
Sub fillTablesFromCSV(db As sqlite3 Ptr)
|
|
Dim As Integer ff, i
|
|
Dim As String lineaCSV, query
|
|
Dim As ZString Ptr errMsg = NULL
|
|
|
|
ff = Freefile
|
|
Open "patients.csv" For Input As #ff
|
|
Line Input #ff, lineaCSV ' Saltar la cabecera
|
|
|
|
While Not Eof(ff)
|
|
Line Input #ff, lineaCSV
|
|
Dim As String id = "", lastname = ""
|
|
|
|
i = 1
|
|
While i <= Len(lineaCSV) And Mid(lineaCSV, i, 1) <> ","
|
|
id += Mid(lineaCSV, i, 1)
|
|
i += 1
|
|
Wend
|
|
i += 1 ' Skip the comma
|
|
|
|
While i <= Len(lineaCSV)
|
|
lastname += Mid(lineaCSV, i, 1)
|
|
i += 1
|
|
Wend
|
|
|
|
query = "INSERT INTO patients VALUES (" & id & ", '" & lastname & "');"
|
|
|
|
sqlite3_exec(db, query, NULL, NULL, @errMsg)
|
|
If errMsg <> NULL Then
|
|
Print "Error inserting patient: " & *errMsg
|
|
sqlite3_free(errMsg)
|
|
End If
|
|
Wend
|
|
Close #ff
|
|
|
|
ff = Freefile
|
|
Open "visits.csv" For Input As #ff
|
|
Line Input #ff, lineaCSV ' Skip header
|
|
|
|
While Not Eof(ff)
|
|
Line Input #ff, lineaCSV
|
|
Dim As String id = "", dateStr = "", score = ""
|
|
Dim As Integer fieldNum = 0
|
|
|
|
For i = 1 To Len(lineaCSV)
|
|
If Mid(lineaCSV, i, 1) = "," Then
|
|
fieldNum += 1
|
|
Else
|
|
Select Case fieldNum
|
|
Case 0: id += Mid(lineaCSV, i, 1)
|
|
Case 1: dateStr += Mid(lineaCSV, i, 1)
|
|
Case 2: score += Mid(lineaCSV, i, 1)
|
|
End Select
|
|
End If
|
|
Next i
|
|
|
|
query = "INSERT INTO visits VALUES (" & id & ", "
|
|
|
|
If dateStr = "" Then
|
|
query &= "NULL, "
|
|
Else
|
|
query &= "'" & dateStr & "', "
|
|
End If
|
|
|
|
If score = "" Then
|
|
query &= "NULL);"
|
|
Else
|
|
query &= score & ");"
|
|
End If
|
|
|
|
sqlite3_exec(db, query, NULL, NULL, @errMsg)
|
|
If errMsg <> NULL Then
|
|
Print "Error inserting visit: " & *errMsg
|
|
sqlite3_free(errMsg)
|
|
End If
|
|
Wend
|
|
Close #ff
|
|
End Sub
|
|
|
|
Function joinTablesAndGroup(db As sqlite3 Ptr) As String
|
|
Dim As sqlite3_stmt Ptr stmt
|
|
Dim As String result = ""
|
|
Dim As ZString Ptr errMsg = NULL
|
|
|
|
Dim As String query = _
|
|
"SELECT " & _
|
|
" p.PATIENT_ID, " & _
|
|
" p.LASTNAME, " & _
|
|
" MAX(v.VISIT_DATE) AS LAST_VISIT, " & _
|
|
" SUM(v.SCORE) AS SCORE_SUM, " & _
|
|
" ROUND(AVG(v.SCORE), 1) AS SCORE_AVG " & _
|
|
"FROM " & _
|
|
" patients p " & _
|
|
"LEFT JOIN " & _
|
|
" visits v ON p.PATIENT_ID = v.PATIENT_ID " & _
|
|
"GROUP BY " & _
|
|
" p.PATIENT_ID, p.LASTNAME " & _
|
|
"ORDER BY " & _
|
|
" p.PATIENT_ID;"
|
|
|
|
If sqlite3_prepare_v2(db, query, -1, @stmt, NULL) <> SQLITE_OK Then
|
|
Print "Error preparing statement: " & *sqlite3_errmsg(db)
|
|
Return "Error"
|
|
End If
|
|
|
|
result = "| PATIENT_ID | LASTNAME | LAST_VISIT | SCORE_SUM | SCORE_AVG |" & Chr(10)
|
|
result &= "|------------|----------|------------|-----------|-----------|" & Chr(10)
|
|
|
|
While sqlite3_step(stmt) = SQLITE_ROW
|
|
Dim As String row = "| "
|
|
|
|
' PATIENT_ID
|
|
If sqlite3_column_type(stmt, 0) <> SQLITE_NULL Then
|
|
row &= " " & Trim(Str(sqlite3_column_int(stmt, 0))) & " | "
|
|
Else
|
|
row &= Space(10) & "| "
|
|
End If
|
|
|
|
' LASTNAME
|
|
If sqlite3_column_type(stmt, 1) <> SQLITE_NULL Then
|
|
Dim As String lastname = *Cast(ZString Ptr, sqlite3_column_text(stmt, 1))
|
|
row &= lastname & Space(9 - Len(lastname)) & "| "
|
|
Else
|
|
row &= " | "
|
|
End If
|
|
|
|
' LAST_VISIT
|
|
If sqlite3_column_type(stmt, 2) <> SQLITE_NULL Then
|
|
Dim As String visit_date = *Cast(ZString Ptr, sqlite3_column_text(stmt, 2))
|
|
row &= visit_date & Space(11 - Len(visit_date)) & "| "
|
|
Else
|
|
row &= " None | "
|
|
End If
|
|
|
|
' SCORE_SUM
|
|
If sqlite3_column_type(stmt, 3) <> SQLITE_NULL Then
|
|
Dim As Double score_sum = sqlite3_column_double(stmt, 3)
|
|
row &= " " & Format(score_sum, "#00.#") & " | "
|
|
Else
|
|
row &= " None | "
|
|
End If
|
|
|
|
' SCORE_AVG
|
|
If sqlite3_column_type(stmt, 4) <> SQLITE_NULL Then
|
|
Dim As Double score_avg = sqlite3_column_double(stmt, 4)
|
|
row &= " " & Format(score_avg, "##.#") & " |"
|
|
Else
|
|
row &= " None |"
|
|
End If
|
|
|
|
result &= row & Chr(10)
|
|
Wend
|
|
|
|
sqlite3_finalize(stmt)
|
|
Return result
|
|
End Function
|
|
|
|
' Main program
|
|
Dim As sqlite3 Ptr db
|
|
Dim As Integer rc
|
|
|
|
createCSVfiles()
|
|
|
|
rc = sqlite3_open(":memory:", @db)
|
|
If rc <> SQLITE_OK Then
|
|
Print "Error opening database: " & *sqlite3_errmsg(db)
|
|
sqlite3_close(db)
|
|
Sleep: End 1
|
|
End If
|
|
|
|
createTableHeaders(db)
|
|
|
|
fillTablesFromCSV(db)
|
|
|
|
Dim As String result = joinTablesAndGroup(db)
|
|
Print result
|
|
|
|
sqlite3_close(db)
|
|
|
|
Sleep
|