I think I understand why you are suggesting to begin with UPDATE, since most (all?) of the exercises require it. If it’s all the same to you, I’m planning to write the SELECT concept doc first, because it feels like a more natural place to start (If you’re curious about my reasoning, see below). I am nearly done with a first draft for SELECT; how about I start a PR with that for review, and then we can discuss the following steps?
If I was going to introduce SQL/SQLite to a new learner, I would go in this order: SELECT, CREATE/INSERT, UPDATE. The reason is that I would imagine the following dialog between a student and instructor:
Student: Why should I learn SQL/SQLite? Instructor: SQLite is a fast, lightweight database that supports SQL, and SQL is the lingua franca for bridging databases with software applications. Student: Well, why should I care about databases? Instructor: Databases provide structured, persistent data that can be retrieved in a predictable, scalable manner. Student: How can I retrieve data from a database? Instructor: Let’s look at the SELECT statement.
Student: OK, how can I put my own data into a database? Instructor: Let’s examine the CREATE and INSERT INTO statements.
Student: How can I modify existing data in a database? Instructor: Let’s explore the UPDATE statement.
Generally speaking, SELECT is the obvious place to start with SQL. However, the track starts with Hello World which requires an UPDATE, which is why I suggested that as the start. In the end, either should work fine.
I don’t know if it’s the best place to comment about but there’s a way to make SELECTs works with the test framework without “manual” UPDATE using only the sqlite interpreter. The main problems for this approach are:
need to run stub file two times (one for show data and other one to colleted the solutions).
some queries will need an alias to make things works properly.
(*I never have tried this on any solution that I made.)
Can you elaborate on your objections to the multi-file approach? I claim that my proposed approach will work with the existing framework – if by “framework” we mean the existing test runner in GitHub - exercism/sqlite-test-runner.
If we instead introduce UPDATE, how would you envision that working? How would you introduce the concept in the syllabus? How would it impact a SELECT-focused exercise?
None of the other tracks/exercises on the website are built around a multi-file solution. C++ does use header files but the “main” logic is still the .cpp file. I’m worried the multi-file direction makes files harder to discover, solutions harder to read and doesn’t work with the overall Exercism flow.
For UPDATE, as I mentioned earlier that could be the first concept. That tracks with how the Hello World uses an UPDATE. (1) Optionally introduce the concept of databases. (2) Explain how UPDATE can be used to modify a table. (3) Move on to SELECT as the next concept.
Alternatively, a stub could be provides with the query skeleton that already populates the solution with an UPDATE based on a SELECT subquery. Tell the students not to change the UPDATE bits nor worry about it and that it will be discussed later. Have them write the SELECT bits.
I’d always love feedback from the other maintainers, too :D
JavaScript/TypeScript has quite a few “multi-file” exercises, but all of the non-main files are read-only (editor only) files. One of the reasons we decided to do that was also because we did have multi-file things for a short while and people got stuck.
So even though I do think it could be a good and cool solution for CLI-only tracks, I do recommend all statements should be written in the same file (by students).
For a single SELECT exercise, some … additional prints should be fine. However, I’m worried about the usability of the test output. If we dump this into one text output and treat it as a single test, it’ll be hard to tell the user which task/test failed. If they touch a print line, it becomes pretty hard for them to know what’s going on.
If we print as JSON output, we could check each test, but that would involve a fair bit of one-off test tooling, which is a non-trivial maintenance cost.
For TypeScript I had a similar issue and solved it adding custom key-values to config.json to sometimes run different tooling. That way I could keep the generic implementation but make it special for a select few ones.
I think we can run multiple tests on the single output, and thus split the exercise into several tasks. If the single output becomes problematic, we could add .output lines to dump the result of each SELECT into a separate output file. And I think we could easily handle the cases where the user mistakenly removes the required .print and/or .output boilerplate lines. How about I try to get it working in the draft PR, then we can all throw darts at it?
I’m sure you could get it working ;) I’m concerned about how complicated and bespoke it will be, and the associated costs. But you’re welcome to try and cook something up.
You could use awk/grep/sed to parse the output and make sure it has all the expected headings and parse those into the per-test outputs.
You could even use grep or comm to ensure the .print is still a .print and that the user didn’t somehow use a SELECT to generate the headings.
There’s no way to differentiate in text output between a formatted string output vs a SELECT that retrieves multiple columns. Treating output as text looses these important semantics.
Some customization in a test running for this one-off SELECT exercise may be fine but I don’t think it’s worth having an involves test runner for one specific exercise when the existing setup could work just fine. We can prepopulate some .print lines and tell users not to touch them. We could just as easily prepopulate the UPDATE bits, too.