Ed, I understand your point and I did use AI to explore some of the questions I
had about DuckDb, but there are things that made me post my post yesterday:
1) I really want to take advantage of some of the features I see in DuckDB
where I can expand the VFP work I'm already doing in the data conversion
market. I have 30 years' worth of library code I've built and frameworks I've
constructed specifically for the niche market I serve and I don't want to leave
that behind. Right or wrong that's where I am and I'll probably be writing in
Foxpro until they pry the keyboard from my cold, dead hands. However, after I
posted my message yesterday, I continued doing some testing with the CLI
version of DuckDB and found I could accomplish some of my wishes without a
32-bit ODBC driver. These are rough tests, but they will give you an idea of
what I'm doing:
* Extract Selected Fields from CSV file without importing and write results to
another CSV file (Time to process over 1000 records: 1 second)
*****************************************************************************************************************
TEXT TO lcCmdString NOSHOW
c:\duckdb\cli\duckdb.exe -c "COPY (SELECT emplid, prefix, fname, mname, lname,
suffix, rstate FROM 'c:/duckdb/empls.csv') TO 'c:/duckdb/test.csv' (HEADER);"
ENDTEXT
RUN &lcCmdString
* Import JSON file, extract one field and save results to CSV File (Time was
under 1 second, but it was a very small JSON file)
****************************************************************************************************
TEXT TO lcCmdString NOSHOW
c:\duckdb\cli\duckdb.exe -c "COPY (SELECT address1 FROM 'c:/duckdb/fcc.json')
TO 'c:/duckdb/jsontocsv.csv' (HEADER);"
ENDTEXT
RUN &lcCmdString
* Import CSV File and Save as SQLite Database then Query the SQLite Database
from VFP
* This snippet also hides the CMD window (Source file contained 485K records.
Time to process: 2.35 seconds)
* Note: The lcCmdString includes a series of SQL statements passed as a single
string delimited by semi-colon
******************************************************************************************
LOCAL loShell, lcCmdString, lnResult
CLEAR
a = SECONDS()
loShell = CREATEOBJECT("WScript.Shell")
TEXT TO lcCmdString NOSHOW
c:\duckdb\cli\duckdb.exe -c "INSTALL sqlite;LOAD sqlite;ATTACH
'C:/Duckdb/wages.sqlite' AS sqlite_db (TYPE sqlite);CREATE TABLE
sqlite_db.wages AS (SELECT * FROM read_csv_auto('C:/duckdb/wages.csv'));DETACH
sqlite_db;"
ENDTEXT
* 0 = hide window
* .T. = wait until the command finishes
lnResult = loShell.Run(lcCmdString, 0, .T.)
IF lnResult <> 0
MESSAGEBOX("DuckDB returned error code " + TRANSFORM(lnResult))
ELSE
b = SECONDS()
? "time: " + ALLTRIM(TRANSFORM(b-a)) + " seconds"
ENDIF
lcDSNLess = "DRIVER={SQLite3 ODBC Driver};Database=C:\DuckDb\wages.sqlite;"
lnConnection = SQLSTRINGCONNECT(lcDSNLess)
IF lnConnection > 1
TEXT TO lcSQLCmd NOSHOW
SELECT DISTINCT CAST([pay_type_description] as varchar(40)) as ptype
from wages
ENDTEXT
SQLEXEC(lnConnection, lcSQLCmd, "PayTypes")
ENDIF
2) I would rather post to this group and ask for help in most cases, because
there is no AI in the world that can match the wide range of knowledge
contained in the heads of the members here nor can they program an AI to
include the attitudes, sense of humor and snarky comebacks that I've come to
know and love.
I've accomplished my first goal with DuckDb which was to determine if there was
even a way to use it with VFP. The answer is yes. Once again, the Fox gives me
the freedom to do amazing things including incorporate completely new
technologies and different tools in ways that help me maximize what I can do
for my clients. Has anyone else worked with DuckDb in any way? The CLI version
is 40Mb and runs incredibly fast from what I can see.
PS: I've also been playing around with Lazarus some of late and using Duck.ai
to try help me learn it. I've had to put it down for a while, but I find the
Lazarus IDE very familiar and easy to use.
Thanks!
Paul H. Tarver
Tarver Program Consultants, Inc.
-----Original Message-----
From: Edward Leafe <[email protected]>
Sent: Thursday, August 27, 2026 8:46 PM
To: ProFox Email List <[email protected]>
Subject: Re: DuckDb & Foxpro
On Aug 27, 2026, at 10:12, [email protected] wrote:
>
> I have at least learned that currently they only have a 64bit ODBC
> driver which means I'd probably have to use VFA64 to use this method
> of connecting to the data, but DuckDB supports multiple API's so I may
> have to use those alternatives instead. As I said, I'm just starting
> to getting into this, so any ideas would be appreciated.
Is there a reason, other than it’s what you know best, that you have to work
with VFP for this? I always think that this is a perfect time to try something
new. Of course you know I’d recommend Python, especially since it has great
support, but really the choice can be anything.
I wasn’t going to send a reply like this, until I saw Kurt’s post just now. You
have an amazing new tool available to help you learn! For example, recently I
wanted to try learning Rust. I have a script that I wrote years ago that I
posted about recently (https://leafe.com/archives/msg/518759) that analyzes the
accumulated suspected spam, and presents it in a report that is emailed to me.
That original script was written in Python, but about 5-6 years ago I re-wrote
it in Go, because it was the latest hotness, and I wanted to get a feel for it.
This week I re-wrote it again in Rust, but instead of trying, failing, trying
to search for the error, I worked with Claude Code to do it. Now I could have
told Claude to just write it by itself, but instead I described the project and
told it that I wanted it to create a tutorial environment for learning the
language. I would ask questions like ‘is there a preferred email parsing
tool?’, and Claude would search for the current status of email processing, and
put together a basic script for parsing an mbox into separate emails. I looked
at that script and didn’t understand most of it, so I would ask Claude to
explain each part that wasn’t clear. Here’s a sample of the Rust code:
let data = fs::read(&spam_file)
.with_context(|| format!("failed to read {}", spam_file.display()))?;
log::line(&format!(
"spammail: {} bytes -> {}",
data.len(),
spam_file.display()
))?;
let raw_messages = mbox::split(&data);
let parser = MessageParser::default();
There’s a lot there that was gibberish to me at first, but I would ask Claude
to explain each bit, and it started to make sense. I’m certainly not a Rust
expert by any means, but I’m at the point where I can read code like that and
understand what it’s doing. With a built-in teacher like Claude, why not try
something new?
-- Ed Leafe
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance:
https://lists.leafe.com/postorius/lists/profoxtech.leafe.com/
To unsubscribe send an email to [email protected] Full version of this
list, including off-topic messages:
https://lists.leafe.com/postorius/lists/profox.leafe.com/
Searchable Archive: https://leafe.com/archives This message:
https://leafe.com/archives/byMID/[email protected]
** All postings, unless explicitly stated otherwise, are the opinions of the
author, and do not constitute legal or medical advice. This statement is added
to the messages for those lawyers who are too stupid to see the obvious
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance:
https://lists.leafe.com/postorius/lists/profox.leafe.com/
To unsubscribe send an email to [email protected]
OT-free version of this list:
https://lists.leafe.com/postorius/lists/profoxtech.leafe.com/
Searchable Archive: https://leafe.com/archives
This message:
https://leafe.com/archives/byMID/[email protected]
** All postings, unless explicitly stated otherwise, are the opinions of the
author, and do not constitute legal or medical advice. This statement is added
to the messages for those lawyers who are too stupid to see the obvious