From d67a26b3891a8d093aaa3a53e0f9a7bfeb0a599e Mon Sep 17 00:00:00 2001
From: "yulai.linda@gmail.com" <rongxinliu.dev@gmail.com>
Date: Thu, 2 May 2024 12:22:33 -0400
Subject: [PATCH 1/7] updated actions/github-script to version v7

---
 .github/workflows/main.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 0f14704..0b0ee1a 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -56,7 +56,7 @@ jobs:
 
     - name: Create Release
       if: ${{ github.ref == 'refs/heads/main' }}
-      uses: actions/github-script@v6
+      uses: actions/github-script@v7
       with:
         github-token: ${{ github.token }}
         script: |

From 2d5fd94132accb2733833eb273d755803a99794c Mon Sep 17 00:00:00 2001
From: "David J. Malan" <malan@harvard.edu>
Date: Mon, 14 Oct 2024 20:39:22 -0400
Subject: [PATCH 2/7] adds support for VACUUM

---
 setup.py        | 2 +-
 src/cs50/sql.py | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/setup.py b/setup.py
index 6fd6cfa..1817b95 100644
--- a/setup.py
+++ b/setup.py
@@ -18,5 +18,5 @@
     package_dir={"": "src"},
     packages=["cs50"],
     url="https://github.com/cs50/python-cs50",
-    version="9.3.4"
+    version="9.4.0"
 )
diff --git a/src/cs50/sql.py b/src/cs50/sql.py
index cbbd3d2..a133293 100644
--- a/src/cs50/sql.py
+++ b/src/cs50/sql.py
@@ -177,6 +177,7 @@ def execute(self, sql, *args, **kwargs):
             "SELECT",
             "START",
             "UPDATE",
+            "VACUUM",
         }
 
         # Check if the full_statement starts with any command
@@ -378,7 +379,7 @@ def teardown_appcontext(exception):
                 )
 
                 # Check for start of transaction
-                if command in ["BEGIN", "START"]:
+                if command in ["BEGIN", "START", "VACUUM"]:  # cannot VACUUM from within a transaction
                     self._autocommit = False
 
                 # Execute statement
@@ -389,7 +390,7 @@ def teardown_appcontext(exception):
                     connection.execute(sqlalchemy.text("COMMIT"))
 
                 # Check for end of transaction
-                if command in ["COMMIT", "ROLLBACK"]:
+                if command in ["COMMIT", "ROLLBACK", "VACUUM"]:  # cannot VACUUM from within a transaction
                     self._autocommit = True
 
                 # Return value

From f81a0a3920d90296537843d45683ec0b5d70171b Mon Sep 17 00:00:00 2001
From: "David J. Malan" <malan@harvard.edu>
Date: Mon, 14 Oct 2024 20:40:31 -0400
Subject: [PATCH 3/7] fixes raw strings

---
 src/cs50/sql.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/cs50/sql.py b/src/cs50/sql.py
index a133293..81905bc 100644
--- a/src/cs50/sql.py
+++ b/src/cs50/sql.py
@@ -329,12 +329,12 @@ def execute(self, sql, *args, **kwargs):
                 sqlparse.tokens.Literal.String,
                 sqlparse.tokens.Literal.String.Single,
             ]:
-                token.value = re.sub("(^'|\s+):", r"\1\:", token.value)
+                token.value = re.sub(r"(^'|\s+):", r"\1\:", token.value)
 
             # In identifier
             # https://www.sqlite.org/lang_keywords.html
             elif token.ttype == sqlparse.tokens.Literal.String.Symbol:
-                token.value = re.sub('(^"|\s+):', r"\1\:", token.value)
+                token.value = re.sub(r'(^"|\s+):', r"\1\:", token.value)
 
         # Join tokens into statement
         statement = "".join([str(token) for token in tokens])

From b629b6dcdf3041982117801a35c01be2b72cb3d3 Mon Sep 17 00:00:00 2001
From: "David J. Malan" <malan@harvard.edu>
Date: Sat, 5 Apr 2025 11:36:15 -0400
Subject: [PATCH 4/7] Update README.md

---
 README.md | 47 -----------------------------------------------
 1 file changed, 47 deletions(-)

diff --git a/README.md b/README.md
index c94bd1f..a9033c6 100644
--- a/README.md
+++ b/README.md
@@ -39,50 +39,3 @@ s = cs50.get_string();
     ```
     python tests/sql.py
     ```
-
-### Sample Tests
-
-```
-import cs50
-db = cs50.SQL("sqlite:///foo.db")
-db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER PRIMARY KEY, val TEXT, bin BLOB)")
-db.execute("INSERT INTO cs50 (val) VALUES('a')")
-db.execute("INSERT INTO cs50 (val) VALUES('b')")
-db.execute("BEGIN")
-db.execute("INSERT INTO cs50 (val) VALUES('c')")
-db.execute("INSERT INTO cs50 (val) VALUES('x')")
-db.execute("INSERT INTO cs50 (val) VALUES('y')")
-db.execute("ROLLBACK")
-db.execute("INSERT INTO cs50 (val) VALUES('z')")
-db.execute("COMMIT")
-
----
-
-import cs50
-db = cs50.SQL("mysql://root@localhost/test")
-db.execute("CREATE TABLE IF NOT EXISTS cs50 (id INTEGER PRIMARY KEY, val TEXT, bin BLOB)")
-db.execute("INSERT INTO cs50 (val) VALUES('a')")
-db.execute("INSERT INTO cs50 (val) VALUES('b')")
-db.execute("BEGIN")
-db.execute("INSERT INTO cs50 (val) VALUES('c')")
-db.execute("INSERT INTO cs50 (val) VALUES('x')")
-db.execute("INSERT INTO cs50 (val) VALUES('y')")
-db.execute("ROLLBACK")
-db.execute("INSERT INTO cs50 (val) VALUES('z')")
-db.execute("COMMIT")
-
----
-
-import cs50
-db = cs50.SQL("postgresql://postgres@localhost/test")
-db.execute("CREATE TABLE IF NOT EXISTS cs50 (id SERIAL PRIMARY KEY, val VARCHAR(16), bin BYTEA)")
-db.execute("INSERT INTO cs50 (val) VALUES('a')")
-db.execute("INSERT INTO cs50 (val) VALUES('b')")
-db.execute("BEGIN")
-db.execute("INSERT INTO cs50 (val) VALUES('c')")
-db.execute("INSERT INTO cs50 (val) VALUES('x')")
-db.execute("INSERT INTO cs50 (val) VALUES('y')")
-db.execute("ROLLBACK")
-db.execute("INSERT INTO cs50 (val) VALUES('z')")
-db.execute("COMMIT")
-```

From 68f4380757d8adb92d027c42c2099e798bff9488 Mon Sep 17 00:00:00 2001
From: "David J. Malan" <malan@harvard.edu>
Date: Sat, 5 Apr 2025 11:38:49 -0400
Subject: [PATCH 5/7] updated Python for Action

---
 .github/workflows/main.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 0b0ee1a..7fcb507 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -23,7 +23,7 @@ jobs:
     - uses: actions/checkout@v4
     - uses: actions/setup-python@v5
       with:
-        python-version: '3.7'
+        python-version: '3.12'
         check-latest: true
     - name: Setup databases
       run: |

From b37a00f2f9b16fea9750b3ee6ca8f9d3ed5c1aa1 Mon Sep 17 00:00:00 2001
From: "David J. Malan" <malan@harvard.edu>
Date: Sat, 12 Apr 2025 13:32:57 -0400
Subject: [PATCH 6/7] added pkg-config

---
 Dockerfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Dockerfile b/Dockerfile
index ccc4552..dddd430 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,6 @@
 FROM cs50/cli
 
-RUN sudo apt update && sudo apt install --yes libmysqlclient-dev pgloader postgresql
+RUN sudo apt update && sudo apt install --yes libmysqlclient-dev pgloader pkg-config postgresql
 RUN sudo pip3 install mysqlclient psycopg2-binary
 
 WORKDIR /mnt

From 99cc280cf83eaea5c08319492ad4d9d1ebc0bd15 Mon Sep 17 00:00:00 2001
From: "David J. Malan" <malan@harvard.edu>
Date: Sat, 12 Apr 2025 13:33:53 -0400
Subject: [PATCH 7/7] removed version

---
 docker-compose.yml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/docker-compose.yml b/docker-compose.yml
index 8608080..bcca424 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -31,4 +31,3 @@ services:
       POSTGRES_DB: test
     ports:
     - 5432:5432
-version: "3.6"