Database Management: The program opens a DuckDB database file named test.db.
Table Creation: It creates a table called users with fields id and name if it doesn't already exist.
Data Insertion: Inserts sample data into the users table: (1, 'John Doe'), (2, 'Peek Snow'), (3, 'Mark Python').
Query Execution: Executes a SQL query to select all records from the users table.
Result Display: Displays the query results in a user-friendly ListIconGadget window, complete with dynamic column headers based on the query output.
This code demonstrates basic interaction with a DuckDB database using PureBasic, including opening a database, executing a query, and displaying the results in a user interface element.
read: https://duckdb.org/docs/index
download: https://duckdb.org/docs/installation/?v ... ure=x86_64
Code: Select all
; PureBasic program to open a DuckDB database, create a table, insert data, and execute a query, displaying results in a ListIconGadget
; Written by: zippo # 2024-08-28 # 2024-08-27 #
; -- read:: https://duckdb.org/why_duckdb
; -- download:: https://duckdb.org/docs/installation/?version=stable&environment=cplusplus&platform=win&download_method=direct&architecture=x86_64
; -- copy duckdb.dll in dir
;--
Prototype.i DuckDBOpen(filename.p-utf8, *db)
Prototype.i DuckDBConnect(*db, *connection)
Prototype.i DuckDBQuery(*connection, query.p-utf8, *out_result)
Prototype.i DuckDBDestroyResult(*result)
Prototype.i DuckDBResultError(*result)
Prototype.q DuckDBRowCount(*result)
Prototype.q DuckDBColumnCount(*result)
Prototype.i DuckDBValueInt32(*result, column.i, row.q)
Prototype.i DuckDBValueVarchar(*result, column.i, row.q)
Prototype.i DuckDBColumnName(*result, column.i)
#DuckDBSuccess = 0
#DuckDBError = 1
Structure DuckDBResult
columns.i
rows.i
Data.i
error.i
EndStructure
If OpenLibrary(0, "duckdb.dll")
Global DuckDBOpen.DuckDBOpen = GetFunction(0, "duckdb_open")
Global DuckDBConnect.DuckDBConnect = GetFunction(0, "duckdb_connect")
Global DuckDBQuery.DuckDBQuery = GetFunction(0, "duckdb_query")
Global DuckDBDestroyResult.DuckDBDestroyResult = GetFunction(0, "duckdb_destroy_result")
Global DuckDBResultError.DuckDBResultError = GetFunction(0, "duckdb_result_error")
Global DuckDBRowCount.DuckDBRowCount = GetFunction(0, "duckdb_row_count")
Global DuckDBColumnCount.DuckDBColumnCount = GetFunction(0, "duckdb_column_count")
Global DuckDBValueInt32.DuckDBValueInt32 = GetFunction(0, "duckdb_value_int32")
Global DuckDBValueVarchar.DuckDBValueVarchar = GetFunction(0, "duckdb_value_varchar")
Global DuckDBColumnName.DuckDBColumnName = GetFunction(0, "duckdb_column_name")
If DuckDBOpen = #Null Or DuckDBConnect = #Null Or DuckDBQuery = #Null Or DuckDBDestroyResult = #Null Or DuckDBResultError = #Null Or DuckDBRowCount = #Null Or DuckDBColumnCount = #Null Or DuckDBValueInt32 = #Null Or DuckDBValueVarchar = #Null Or DuckDBColumnName = #Null
MessageRequester("Error", "Failed to load DuckDB functions", #PB_MessageRequester_Ok)
End
EndIf
db.i
connection.i
result.DuckDBResult
If DuckDBOpen("test.db", @db) = #DuckDBSuccess
Debug "Database opened successfully."
If DuckDBConnect(db, @connection) = #DuckDBSuccess
Debug "Connected to the database."
; Create the users table
createTableQuery.s = "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name VARCHAR);"
status.i = DuckDBQuery(connection, createTableQuery, @result)
If status = #DuckDBSuccess
Debug "Table created successfully."
; Insert data into the users table
insertDataQuery.s = "INSERT INTO users (id, name) VALUES (1, 'John Doe'), (2, 'Peek Snow'), (3, 'Mark Python');"
status = DuckDBQuery(connection, insertDataQuery, @result)
If status = #DuckDBSuccess
Debug "Data inserted successfully."
; Execute the query to select data from the users table
selectQuery.s = "SELECT id, name FROM users;"
status = DuckDBQuery(connection, selectQuery, @result)
If status = #DuckDBSuccess
Debug "Query executed successfully."
rows.q = DuckDBRowCount(@result)
cols.q = DuckDBColumnCount(@result)
Debug "Number of rows: " + Str(rows)
Debug "Number of columns: " + Str(cols)
; Create a window with a ListIconGadget
If OpenWindow(0, 0, 0, 640, 480, "DuckDB Query Results", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
ListIconGadget(0, 10, 10, 620, 460, "", 100, #PB_ListIcon_GridLines | #PB_ListIcon_FullRowSelect)
; Add dynamic columns based on the query results
For col.q = 0 To cols - 1
columnNamePtr.i = DuckDBColumnName(@result, col)
If columnNamePtr = 0
columnName.s = "Column " + Str(col)
Else
columnName.s = PeekS(columnNamePtr, -1, #PB_UTF8)
EndIf
AddGadgetColumn(0, col, columnName, 200)
Next col
If rows > 0 And cols > 0
For row.q = 0 To rows - 1
itemText.s = ""
For col.q = 0 To cols - 1
If col > 0
itemText + Chr(10)
EndIf
valuePtr.i = DuckDBValueVarchar(@result, col, row)
If valuePtr = 0
itemText + "NULL"
Else
itemText + PeekS(valuePtr, -1, #PB_UTF8)
EndIf
Next col
AddGadgetItem(0, row, itemText)
Next row
Else
Debug "No rows returned by the query."
EndIf
; Wait for the user to close the window
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
; Free the query result
DuckDBDestroyResult(@result)
Else
Debug "Failed to open window."
DuckDBDestroyResult(@result)
EndIf
Else
errorMessage$ = PeekS(DuckDBResultError(@result))
Debug "Query failed: " + errorMessage$
; Free the query result even if the query is unsuccessful
DuckDBDestroyResult(@result)
EndIf
Else
errorMessage$ = PeekS(DuckDBResultError(@result))
Debug "Data insertion failed: " + errorMessage$
; Free the query result even if the data insertion is unsuccessful
DuckDBDestroyResult(@result)
EndIf
Else
errorMessage$ = PeekS(DuckDBResultError(@result))
Debug "Table creation failed: " + errorMessage$
; Free the query result even if the table creation is unsuccessful
DuckDBDestroyResult(@result)
EndIf
Else
Debug "Failed to connect to the database."
EndIf
Else
Debug "Failed to open database."
EndIf
CloseLibrary(0)
Else
MessageRequester("Error", "Failed to load DuckDB library", #PB_MessageRequester_Ok)
EndIf
End
