diff --git a/compiled_starters/java/.gitattributes b/compiled_starters/java/.gitattributes
new file mode 100644
index 0000000..176a458
--- /dev/null
+++ b/compiled_starters/java/.gitattributes
@@ -0,0 +1 @@
+* text=auto
diff --git a/compiled_starters/java/.gitignore b/compiled_starters/java/.gitignore
new file mode 100644
index 0000000..74cc3e4
--- /dev/null
+++ b/compiled_starters/java/.gitignore
@@ -0,0 +1,4 @@
+java_sqlite.jar
+target/*
+target/
+.idea/
\ No newline at end of file
diff --git a/compiled_starters/java/README.md b/compiled_starters/java/README.md
new file mode 100644
index 0000000..a15dd6c
--- /dev/null
+++ b/compiled_starters/java/README.md
@@ -0,0 +1,78 @@
+
+
+This is a starting point for Java solutions to the
+["Build Your Own SQLite" Challenge](https://codecrafters.io/challenges/sqlite).
+
+In this challenge, you'll build a barebones SQLite implementation that supports
+basic SQL queries like `SELECT`. Along the way we'll learn about
+[SQLite's file format](https://www.sqlite.org/fileformat.html), how indexed data
+is
+[stored in B-trees](https://jvns.ca/blog/2014/10/02/how-does-sqlite-work-part-2-btrees/)
+and more.
+
+**Note**: If you're viewing this repo on GitHub, head over to
+[codecrafters.io](https://codecrafters.io) to try the challenge.
+
+# Passing the first stage
+
+The entry point for your SQLite implementation is in `src/main/java/Main.java`.
+Study and uncomment the relevant code, and push your changes to pass the first
+stage:
+
+```sh
+git add .
+git commit -m "pass 1st stage" # any msg
+git push origin master
+```
+
+Time to move on to the next stage!
+
+# Stage 2 & beyond
+
+Note: This section is for stages 2 and beyond.
+
+1. Ensure you have `java (21)` installed locally
+1. Run `./your_sqlite3.sh` to run your program, which is implemented in
+ `src/main/java/Main.java`.
+1. Commit your changes and run `git push origin master` to submit your solution
+ to CodeCrafters. Test output will be streamed to your terminal.
+
+# Sample Databases
+
+To make it easy to test queries locally, we've added a sample database in the
+root of this repository: `sample.db`.
+
+This contains two tables: `apples` & `oranges`. You can use this to test your
+implementation for the first 6 stages.
+
+You can explore this database by running queries against it like this:
+
+```sh
+$ sqlite3 sample.db "select id, name from apples"
+1|Granny Smith
+2|Fuji
+3|Honeycrisp
+4|Golden Delicious
+```
+
+There are two other databases that you can use:
+
+1. `superheroes.db`:
+ - This is a small version of the test database used in the table-scan stage.
+ - It contains one table: `superheroes`.
+ - It is ~1MB in size.
+1. `companies.db`:
+ - This is a small version of the test database used in the index-scan stage.
+ - It contains one table: `companies`, and one index: `idx_companies_country`
+ - It is ~7MB in size.
+
+These aren't included in the repository because they're large in size. You can
+download them by running this script:
+
+```sh
+./download_sample_databases.sh
+```
+
+If the script doesn't work for some reason, you can download the databases
+directly from
+[codecrafters-io/sample-sqlite-databases](https://github.com/codecrafters-io/sample-sqlite-databases).
diff --git a/compiled_starters/java/codecrafters.yml b/compiled_starters/java/codecrafters.yml
new file mode 100644
index 0000000..7384f15
--- /dev/null
+++ b/compiled_starters/java/codecrafters.yml
@@ -0,0 +1,11 @@
+# Set this to true if you want debug logs.
+#
+# These can be VERY verbose, so we suggest turning them off
+# unless you really need them.
+debug: false
+
+# Use this to change the Java version used to run your code
+# on Codecrafters.
+#
+# Available versions: java-21
+language_pack: java-21
diff --git a/compiled_starters/java/download_sample_databases.sh b/compiled_starters/java/download_sample_databases.sh
new file mode 100755
index 0000000..03e0573
--- /dev/null
+++ b/compiled_starters/java/download_sample_databases.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+echo "Downloading superheroes.db: ~1MB (used in stage 7)"
+curl -Lo superheroes.db https://raw.githubusercontent.com/codecrafters-io/sample-sqlite-databases/master/superheroes.db
+
+echo "Downloading companies.db: ~7MB (used in stage 8)"
+curl -Lo companies.db https://raw.githubusercontent.com/codecrafters-io/sample-sqlite-databases/master/companies.db
+
+echo "Sample databases downloaded."
diff --git a/compiled_starters/java/pom.xml b/compiled_starters/java/pom.xml
new file mode 100644
index 0000000..c483c23
--- /dev/null
+++ b/compiled_starters/java/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+ io.codecrafters
+ build-your-own-sqlite
+ 1.0
+
+
+ 21
+ 21
+ UTF-8
+ 21
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+ java_sqlite
+
+ jar-with-dependencies
+
+ false
+
+
+ true
+
+ Main
+
+
+ ${dir}
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/compiled_starters/java/sample.db b/compiled_starters/java/sample.db
new file mode 100644
index 0000000..687673e
Binary files /dev/null and b/compiled_starters/java/sample.db differ
diff --git a/compiled_starters/java/src/main/java/Main.java b/compiled_starters/java/src/main/java/Main.java
new file mode 100644
index 0000000..e4d6fe7
--- /dev/null
+++ b/compiled_starters/java/src/main/java/Main.java
@@ -0,0 +1,38 @@
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class Main {
+ public static void main(String[] args){
+ if (args.length < 2) {
+ System.out.println("Missing and ");
+ return;
+ }
+
+ String databaseFilePath = args[0];
+ String command = args[1];
+
+ switch (command) {
+ case ".dbinfo" -> {
+ try {
+ byte[] header = Files.readAllBytes(Path.of(databaseFilePath));
+
+ // The page size is stored at the 16th byte offset, using 2 bytes in big-endian order.
+ // '& 0xFFFF' is used to convert the signed short to an unsigned int.
+ int pageSize = ByteBuffer.wrap(header).order(ByteOrder.BIG_ENDIAN).position(16).getShort() & 0xFFFF;
+
+ // You can use print statements as follows for debugging, they'll be visible when running tests.
+ System.out.println("Logs from your program will appear here!");
+
+ // Uncomment this block to pass the first stage
+ // System.out.println("database page size: " + pageSize);
+ } catch (IOException e) {
+ System.out.println("Error reading file: " + e.getMessage());
+ }
+ }
+ default -> System.out.println("Missing or invalid command passed: " + command);
+ }
+ }
+}
diff --git a/compiled_starters/java/your_sqlite3.sh b/compiled_starters/java/your_sqlite3.sh
new file mode 100755
index 0000000..c0d5216
--- /dev/null
+++ b/compiled_starters/java/your_sqlite3.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+#
+# DON'T EDIT THIS!
+#
+# CodeCrafters uses this file to test your code. Don't make any changes here!
+#
+# DON'T EDIT THIS!
+set -e
+mvn -B --quiet package -Ddir=/tmp/codecrafters-sqlite-target
+exec java -jar /tmp/codecrafters-sqlite-target/java_sqlite.jar "$@"
\ No newline at end of file
diff --git a/compiled_starters/javascript/app/main.js b/compiled_starters/javascript/app/main.js
index 5fcdd28..4e5b751 100644
--- a/compiled_starters/javascript/app/main.js
+++ b/compiled_starters/javascript/app/main.js
@@ -9,7 +9,7 @@ if (command === ".dbinfo") {
const { buffer } = await databaseFileHandler.read({
length: 100,
position: 0,
- buffer: Buffer.alloc(100)
+ buffer: Buffer.alloc(100),
});
// You can use print statements as follows for debugging, they'll be visible when running tests.
diff --git a/course-definition.yml b/course-definition.yml
index 1c9b10a..5f6753d 100644
--- a/course-definition.yml
+++ b/course-definition.yml
@@ -28,6 +28,8 @@ languages:
release_status: "alpha"
alpha_tester_usernames: ["Terky"]
- slug: "zig"
+ - slug: "java"
+ release_status: "beta"
marketing:
difficulty: hard
diff --git a/dockerfiles/java-21.Dockerfile b/dockerfiles/java-21.Dockerfile
new file mode 100644
index 0000000..c4eed06
--- /dev/null
+++ b/dockerfiles/java-21.Dockerfile
@@ -0,0 +1,16 @@
+FROM maven:3.9.5-eclipse-temurin-21-alpine
+
+COPY pom.xml /app/pom.xml
+
+WORKDIR /app
+
+# Download the dependencies
+RUN mvn -B package -Ddir=/tmp/codecrafters-sqlite-target
+
+# Cache Dependencies
+RUN mkdir -p /app-cached
+RUN mv /app/target /app-cached # Is this needed?
+
+# Pre-compile steps
+RUN echo "cd \${CODECRAFTERS_SUBMISSION_DIR} && mvn -B package -Ddir=/tmp/codecrafters-sqlite-target && sed -i 's/^\(mvn .*\)/#\1/' ./your_sqlite3.sh" > /codecrafters-precompile.sh
+RUN chmod +x /codecrafters-precompile.sh
\ No newline at end of file
diff --git a/solutions/cpp/01-init/diff/src/Server.cpp.diff b/solutions/cpp/01-init/diff/src/Server.cpp.diff
index 0ec899a..50b6af9 100644
--- a/solutions/cpp/01-init/diff/src/Server.cpp.diff
+++ b/solutions/cpp/01-init/diff/src/Server.cpp.diff
@@ -24,12 +24,12 @@
- // Uncomment this to pass the first stage
- // database_file.seekg(16); // Skip the first 16 bytes of the header
-- //
+- //
- // char buffer[2];
- // database_file.read(buffer, 2);
-- //
+- //
- // unsigned short page_size = (static_cast(buffer[1]) | (static_cast(buffer[0]) << 8));
-- //
+- //
- // std::cout << "database page size: " << page_size << std::endl;
+ database_file.seekg(16); // Skip the first 16 bytes of the header
+
diff --git a/solutions/cpp/01-init/explanation.md b/solutions/cpp/01-init/explanation.md
new file mode 100644
index 0000000..9160aaa
--- /dev/null
+++ b/solutions/cpp/01-init/explanation.md
@@ -0,0 +1,23 @@
+The entry point for your SQLite implementation is in `src/Server.cpp`.
+
+Study and uncomment the relevant code:
+
+```cpp
+// Uncomment this to pass the first stage
+database_file.seekg(16); // Skip the first 16 bytes of the header
+
+char buffer[2];
+database_file.read(buffer, 2);
+
+unsigned short page_size = (static_cast(buffer[1]) | (static_cast(buffer[0]) << 8));
+
+std::cout << "database page size: " << page_size << std::endl;
+```
+
+Push your changes to pass the first stage:
+
+```
+git add .
+git commit -m "pass 1st stage" # any msg
+git push origin master
+```
diff --git a/solutions/csharp/01-init/diff/src/Program.cs.diff b/solutions/csharp/01-init/diff/src/Program.cs.diff
index 8ec971e..a254409 100644
--- a/solutions/csharp/01-init/diff/src/Program.cs.diff
+++ b/solutions/csharp/01-init/diff/src/Program.cs.diff
@@ -1,35 +1,35 @@
@@ -1,29 +1,25 @@
- using static System.Buffers.Binary.BinaryPrimitives;
-
- // Parse arguments
- var (path, command) = args.Length switch
- {
- 0 => throw new InvalidOperationException("Missing and "),
- 1 => throw new InvalidOperationException("Missing "),
- _ => (args[0], args[1])
- };
-
- var databaseFile = File.OpenRead(path);
-
- // Parse command and act accordingly
- if (command == ".dbinfo")
- {
-- // You can use print statements as follows for debugging, they'll be visible when running tests.
-- Console.WriteLine("Logs from your program will appear here!");
--
-- // Uncomment this line to pass the first stage
-- // databaseFile.Seek(16, SeekOrigin.Begin); // Skip the first 16 bytes
-- // byte[] pageSizeBytes = new byte[2];
-- // databaseFile.Read(pageSizeBytes, 0, 2);
-- // var pageSize = ReadUInt16BigEndian(pageSizeBytes);
-- // Console.WriteLine($"database page size: {pageSize}");
-+ databaseFile.Seek(16, SeekOrigin.Begin); // Skip the first 16 bytes
-+ byte[] pageSizeBytes = new byte[2];
-+ databaseFile.Read(pageSizeBytes, 0, 2);
-+ var pageSize = ReadUInt16BigEndian(pageSizeBytes);
-+ Console.WriteLine($"database page size: {pageSize}");
- }
- else
- {
- throw new InvalidOperationException($"Invalid command: {command}");
- }
+ using static System.Buffers.Binary.BinaryPrimitives;
+
+ // Parse arguments
+ var (path, command) = args.Length switch
+ {
+ 0 => throw new InvalidOperationException("Missing and "),
+ 1 => throw new InvalidOperationException("Missing "),
+ _ => (args[0], args[1])
+ };
+
+ var databaseFile = File.OpenRead(path);
+
+ // Parse command and act accordingly
+ if (command == ".dbinfo")
+ {
+- // You can use print statements as follows for debugging, they'll be visible when running tests.
+- Console.WriteLine("Logs from your program will appear here!");
+-
+- // Uncomment this line to pass the first stage
+- // databaseFile.Seek(16, SeekOrigin.Begin); // Skip the first 16 bytes
+- // byte[] pageSizeBytes = new byte[2];
+- // databaseFile.Read(pageSizeBytes, 0, 2);
+- // var pageSize = ReadUInt16BigEndian(pageSizeBytes);
+- // Console.WriteLine($"database page size: {pageSize}");
++ databaseFile.Seek(16, SeekOrigin.Begin); // Skip the first 16 bytes
++ byte[] pageSizeBytes = new byte[2];
++ databaseFile.Read(pageSizeBytes, 0, 2);
++ var pageSize = ReadUInt16BigEndian(pageSizeBytes);
++ Console.WriteLine($"database page size: {pageSize}");
+ }
+ else
+ {
+ throw new InvalidOperationException($"Invalid command: {command}");
+ }
diff --git a/solutions/java/01-init/code/.gitattributes b/solutions/java/01-init/code/.gitattributes
new file mode 100644
index 0000000..176a458
--- /dev/null
+++ b/solutions/java/01-init/code/.gitattributes
@@ -0,0 +1 @@
+* text=auto
diff --git a/solutions/java/01-init/code/.gitignore b/solutions/java/01-init/code/.gitignore
new file mode 100644
index 0000000..74cc3e4
--- /dev/null
+++ b/solutions/java/01-init/code/.gitignore
@@ -0,0 +1,4 @@
+java_sqlite.jar
+target/*
+target/
+.idea/
\ No newline at end of file
diff --git a/solutions/java/01-init/code/README.md b/solutions/java/01-init/code/README.md
new file mode 100644
index 0000000..a15dd6c
--- /dev/null
+++ b/solutions/java/01-init/code/README.md
@@ -0,0 +1,78 @@
+
+
+This is a starting point for Java solutions to the
+["Build Your Own SQLite" Challenge](https://codecrafters.io/challenges/sqlite).
+
+In this challenge, you'll build a barebones SQLite implementation that supports
+basic SQL queries like `SELECT`. Along the way we'll learn about
+[SQLite's file format](https://www.sqlite.org/fileformat.html), how indexed data
+is
+[stored in B-trees](https://jvns.ca/blog/2014/10/02/how-does-sqlite-work-part-2-btrees/)
+and more.
+
+**Note**: If you're viewing this repo on GitHub, head over to
+[codecrafters.io](https://codecrafters.io) to try the challenge.
+
+# Passing the first stage
+
+The entry point for your SQLite implementation is in `src/main/java/Main.java`.
+Study and uncomment the relevant code, and push your changes to pass the first
+stage:
+
+```sh
+git add .
+git commit -m "pass 1st stage" # any msg
+git push origin master
+```
+
+Time to move on to the next stage!
+
+# Stage 2 & beyond
+
+Note: This section is for stages 2 and beyond.
+
+1. Ensure you have `java (21)` installed locally
+1. Run `./your_sqlite3.sh` to run your program, which is implemented in
+ `src/main/java/Main.java`.
+1. Commit your changes and run `git push origin master` to submit your solution
+ to CodeCrafters. Test output will be streamed to your terminal.
+
+# Sample Databases
+
+To make it easy to test queries locally, we've added a sample database in the
+root of this repository: `sample.db`.
+
+This contains two tables: `apples` & `oranges`. You can use this to test your
+implementation for the first 6 stages.
+
+You can explore this database by running queries against it like this:
+
+```sh
+$ sqlite3 sample.db "select id, name from apples"
+1|Granny Smith
+2|Fuji
+3|Honeycrisp
+4|Golden Delicious
+```
+
+There are two other databases that you can use:
+
+1. `superheroes.db`:
+ - This is a small version of the test database used in the table-scan stage.
+ - It contains one table: `superheroes`.
+ - It is ~1MB in size.
+1. `companies.db`:
+ - This is a small version of the test database used in the index-scan stage.
+ - It contains one table: `companies`, and one index: `idx_companies_country`
+ - It is ~7MB in size.
+
+These aren't included in the repository because they're large in size. You can
+download them by running this script:
+
+```sh
+./download_sample_databases.sh
+```
+
+If the script doesn't work for some reason, you can download the databases
+directly from
+[codecrafters-io/sample-sqlite-databases](https://github.com/codecrafters-io/sample-sqlite-databases).
diff --git a/solutions/java/01-init/code/codecrafters.yml b/solutions/java/01-init/code/codecrafters.yml
new file mode 100644
index 0000000..7384f15
--- /dev/null
+++ b/solutions/java/01-init/code/codecrafters.yml
@@ -0,0 +1,11 @@
+# Set this to true if you want debug logs.
+#
+# These can be VERY verbose, so we suggest turning them off
+# unless you really need them.
+debug: false
+
+# Use this to change the Java version used to run your code
+# on Codecrafters.
+#
+# Available versions: java-21
+language_pack: java-21
diff --git a/solutions/java/01-init/code/download_sample_databases.sh b/solutions/java/01-init/code/download_sample_databases.sh
new file mode 100755
index 0000000..03e0573
--- /dev/null
+++ b/solutions/java/01-init/code/download_sample_databases.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+echo "Downloading superheroes.db: ~1MB (used in stage 7)"
+curl -Lo superheroes.db https://raw.githubusercontent.com/codecrafters-io/sample-sqlite-databases/master/superheroes.db
+
+echo "Downloading companies.db: ~7MB (used in stage 8)"
+curl -Lo companies.db https://raw.githubusercontent.com/codecrafters-io/sample-sqlite-databases/master/companies.db
+
+echo "Sample databases downloaded."
diff --git a/solutions/java/01-init/code/pom.xml b/solutions/java/01-init/code/pom.xml
new file mode 100644
index 0000000..c483c23
--- /dev/null
+++ b/solutions/java/01-init/code/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+ io.codecrafters
+ build-your-own-sqlite
+ 1.0
+
+
+ 21
+ 21
+ UTF-8
+ 21
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+ java_sqlite
+
+ jar-with-dependencies
+
+ false
+
+
+ true
+
+ Main
+
+
+ ${dir}
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/solutions/java/01-init/code/sample.db b/solutions/java/01-init/code/sample.db
new file mode 100644
index 0000000..687673e
Binary files /dev/null and b/solutions/java/01-init/code/sample.db differ
diff --git a/solutions/java/01-init/code/src/main/java/Main.java b/solutions/java/01-init/code/src/main/java/Main.java
new file mode 100644
index 0000000..f0ca2e2
--- /dev/null
+++ b/solutions/java/01-init/code/src/main/java/Main.java
@@ -0,0 +1,34 @@
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class Main {
+ public static void main(String[] args){
+ if (args.length < 2) {
+ System.out.println("Missing and ");
+ return;
+ }
+
+ String databaseFilePath = args[0];
+ String command = args[1];
+
+ switch (command) {
+ case ".dbinfo" -> {
+ try {
+ byte[] header = Files.readAllBytes(Path.of(databaseFilePath));
+
+ // The page size is stored at the 16th byte offset, using 2 bytes in big-endian order.
+ // '& 0xFFFF' is used to convert the signed short to an unsigned int.
+ int pageSize = ByteBuffer.wrap(header).order(ByteOrder.BIG_ENDIAN).position(16).getShort() & 0xFFFF;
+
+ System.out.println("database page size: " + pageSize);
+ } catch (IOException e) {
+ System.out.println("Error reading file: " + e.getMessage());
+ }
+ }
+ default -> System.out.println("Missing or invalid command passed: " + command);
+ }
+ }
+}
diff --git a/solutions/java/01-init/code/your_sqlite3.sh b/solutions/java/01-init/code/your_sqlite3.sh
new file mode 100755
index 0000000..c0d5216
--- /dev/null
+++ b/solutions/java/01-init/code/your_sqlite3.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+#
+# DON'T EDIT THIS!
+#
+# CodeCrafters uses this file to test your code. Don't make any changes here!
+#
+# DON'T EDIT THIS!
+set -e
+mvn -B --quiet package -Ddir=/tmp/codecrafters-sqlite-target
+exec java -jar /tmp/codecrafters-sqlite-target/java_sqlite.jar "$@"
\ No newline at end of file
diff --git a/solutions/java/01-init/diff/src/main/java/Main.java.diff b/solutions/java/01-init/diff/src/main/java/Main.java.diff
new file mode 100644
index 0000000..14cd5d2
--- /dev/null
+++ b/solutions/java/01-init/diff/src/main/java/Main.java.diff
@@ -0,0 +1,40 @@
+@@ -1,38 +1,34 @@
+ import java.io.IOException;
+ import java.nio.ByteBuffer;
+ import java.nio.ByteOrder;
+ import java.nio.file.Files;
+ import java.nio.file.Path;
+
+ public class Main {
+ public static void main(String[] args){
+ if (args.length < 2) {
+ System.out.println("Missing and ");
+ return;
+ }
+
+ String databaseFilePath = args[0];
+ String command = args[1];
+
+ switch (command) {
+ case ".dbinfo" -> {
+ try {
+ byte[] header = Files.readAllBytes(Path.of(databaseFilePath));
+
+ // The page size is stored at the 16th byte offset, using 2 bytes in big-endian order.
+ // '& 0xFFFF' is used to convert the signed short to an unsigned int.
+ int pageSize = ByteBuffer.wrap(header).order(ByteOrder.BIG_ENDIAN).position(16).getShort() & 0xFFFF;
+
+- // You can use print statements as follows for debugging, they'll be visible when running tests.
+- System.out.println("Logs from your program will appear here!");
+-
+- // Uncomment this block to pass the first stage
+- // System.out.println("database page size: " + pageSize);
++ System.out.println("database page size: " + pageSize);
+ } catch (IOException e) {
+ System.out.println("Error reading file: " + e.getMessage());
+ }
+ }
+ default -> System.out.println("Missing or invalid command passed: " + command);
+ }
+ }
+ }
diff --git a/solutions/java/01-init/explanation.md b/solutions/java/01-init/explanation.md
new file mode 100644
index 0000000..7fbbf1a
--- /dev/null
+++ b/solutions/java/01-init/explanation.md
@@ -0,0 +1,16 @@
+The entry point for your SQLite implementation is in `src/main/java/Main.java`.
+
+Study and uncomment the relevant code:
+
+```java
+// Uncomment this block to pass the first stage
+System.out.println("database page size: " + pageSize);
+```
+
+Push your changes to pass the first stage:
+
+```
+git add .
+git commit -m "pass 1st stage" # any msg
+git push origin master
+```
diff --git a/solutions/javascript/01-init/code/app/main.js b/solutions/javascript/01-init/code/app/main.js
index 0a56ffc..58fa52b 100644
--- a/solutions/javascript/01-init/code/app/main.js
+++ b/solutions/javascript/01-init/code/app/main.js
@@ -9,7 +9,7 @@ if (command === ".dbinfo") {
const { buffer } = await databaseFileHandler.read({
length: 100,
position: 0,
- buffer: Buffer.alloc(100)
+ buffer: Buffer.alloc(100),
});
const pageSize = buffer.readUInt16BE(16); // page size is 2 bytes starting at offset 16
diff --git a/solutions/javascript/01-init/diff/app/main.js.diff b/solutions/javascript/01-init/diff/app/main.js.diff
index 7bc91ea..b3e64fb 100644
--- a/solutions/javascript/01-init/diff/app/main.js.diff
+++ b/solutions/javascript/01-init/diff/app/main.js.diff
@@ -10,7 +10,7 @@
const { buffer } = await databaseFileHandler.read({
length: 100,
position: 0,
- buffer: Buffer.alloc(100)
+ buffer: Buffer.alloc(100),
});
- // You can use print statements as follows for debugging, they'll be visible when running tests.
diff --git a/solutions/zig/01-init/explanation.md b/solutions/zig/01-init/explanation.md
new file mode 100644
index 0000000..2a17923
--- /dev/null
+++ b/solutions/zig/01-init/explanation.md
@@ -0,0 +1,42 @@
+The entry point for your SQLite implementation is in `app/main.zig`.
+
+Study and uncomment the relevant code:
+
+```zig
+// Uncomment this to pass the first stage
+
+var gpa = std.heap.GeneralPurposeAllocator(.{}){};
+defer _ = gpa.deinit();
+const allocator = gpa.allocator();
+
+const args = try std.process.argsAlloc(allocator);
+defer std.process.argsFree(allocator, args);
+
+
+if (args.len < 3) {
+ try std.io.getStdErr().writer().print("Usage: {s} \n", .{args[0]});
+ return;
+}
+
+var database_file_path: []const u8 = args[1];
+var command: []const u8 = args[2];
+
+if (std.mem.eql(u8, command, ".dbinfo")) {
+ var file = try std.fs.cwd().openFile(database_file_path, .{});
+ defer file.close();
+
+ var buf: [2]u8 = undefined;
+ _ = try file.seekTo(16);
+ _ = try file.read(&buf);
+ const page_size = std.mem.readInt(u16, &buf, .Big);
+ try std.io.getStdOut().writer().print("database page size: {}\n", .{page_size});
+}
+```
+
+Push your changes to pass the first stage:
+
+```
+git add .
+git commit -m "pass 1st stage" # any msg
+git push origin master
+```
diff --git a/starter-repository-definitions.yml b/starter-repository-definitions.yml
index aab47e5..ef48951 100644
--- a/starter-repository-definitions.yml
+++ b/starter-repository-definitions.yml
@@ -6,6 +6,7 @@
target: codecrafters.yml
- source: starter_templates/sample.db
target: sample.db
+ should_skip_template_evaluation: true
- source: starter_templates/download_sample_databases.sh
target: download_sample_databases.sh
- source: starter_templates/python/app/main.py
@@ -32,6 +33,7 @@
target: codecrafters.yml
- source: starter_templates/sample.db
target: sample.db
+ should_skip_template_evaluation: true
- source: starter_templates/download_sample_databases.sh
target: download_sample_databases.sh
- source: starter_templates/go/app/main.go
@@ -58,6 +60,7 @@
target: codecrafters.yml
- source: starter_templates/sample.db
target: sample.db
+ should_skip_template_evaluation: true
- source: starter_templates/download_sample_databases.sh
target: download_sample_databases.sh
- source: starter_templates/javascript/app/main.js
@@ -82,6 +85,7 @@
target: codecrafters.yml
- source: starter_templates/sample.db
target: sample.db
+ should_skip_template_evaluation: true
- source: starter_templates/download_sample_databases.sh
target: download_sample_databases.sh
- source: starter_templates/rust/.gitignore
@@ -108,6 +112,7 @@
target: codecrafters.yml
- source: starter_templates/sample.db
target: sample.db
+ should_skip_template_evaluation: true
- source: starter_templates/download_sample_databases.sh
target: download_sample_databases.sh
- source: starter_templates/csharp/.gitignore
@@ -134,6 +139,7 @@
target: codecrafters.yml
- source: starter_templates/sample.db
target: sample.db
+ should_skip_template_evaluation: true
- source: starter_templates/download_sample_databases.sh
target: download_sample_databases.sh
- source: starter_templates/.gitignore
@@ -156,6 +162,7 @@
target: codecrafters.yml
- source: starter_templates/sample.db
target: sample.db
+ should_skip_template_evaluation: true
- source: starter_templates/download_sample_databases.sh
target: download_sample_databases.sh
- source: starter_templates/swift/.gitignore
@@ -180,6 +187,7 @@
target: codecrafters.yml
- source: starter_templates/sample.db
target: sample.db
+ should_skip_template_evaluation: true
- source: starter_templates/download_sample_databases.sh
target: download_sample_databases.sh
- source: starter_templates/cpp/.gitignore
@@ -204,6 +212,7 @@
target: codecrafters.yml
- source: starter_templates/sample.db
target: sample.db
+ should_skip_template_evaluation: true
- source: starter_templates/download_sample_databases.sh
target: download_sample_databases.sh
- source: starter_templates/zig/.gitignore
@@ -216,4 +225,29 @@
target: .gitattributes
template_attributes:
required_executable: "zig (0.11)"
- user_editable_file: "app/main.zig"
\ No newline at end of file
+ user_editable_file: "app/main.zig"
+
+- language: java
+ file_mappings:
+ - source: starter_templates/README.md
+ target: README.md
+ - source: starter_templates/codecrafters.yml
+ target: codecrafters.yml
+ - source: starter_templates/sample.db
+ target: sample.db
+ should_skip_template_evaluation: true
+ - source: starter_templates/download_sample_databases.sh
+ target: download_sample_databases.sh
+ - source: starter_templates/java/your_sqlite3.sh
+ target: your_sqlite3.sh
+ - source: starter_templates/java/.gitignore
+ target: .gitignore
+ - source: starter_templates/java/src/main/java/Main.java
+ target: src/main/java/Main.java
+ - source: starter_templates/java/pom.xml
+ target: pom.xml
+ - source: starter_templates/.gitattributes
+ target: .gitattributes
+ template_attributes:
+ required_executable: "java (21)"
+ user_editable_file: "src/main/java/Main.java"
diff --git a/starter_templates/codecrafters.yml b/starter_templates/codecrafters.yml
index 27df7be..f990021 100644
--- a/starter_templates/codecrafters.yml
+++ b/starter_templates/codecrafters.yml
@@ -52,8 +52,8 @@ language_pack: elixir-1.10
language_pack: kotlin-1.4
{{/ language_is_kotlin }}
{{# language_is_java }}
-# Available versions: java-1.8
-language_pack: java-1.8
+# Available versions: java-21
+language_pack: java-21
{{/ language_is_java }}
{{# language_is_nim }}
# Available versions: nim-1.0
diff --git a/starter_templates/java/.gitignore b/starter_templates/java/.gitignore
new file mode 100644
index 0000000..74cc3e4
--- /dev/null
+++ b/starter_templates/java/.gitignore
@@ -0,0 +1,4 @@
+java_sqlite.jar
+target/*
+target/
+.idea/
\ No newline at end of file
diff --git a/starter_templates/java/pom.xml b/starter_templates/java/pom.xml
new file mode 100644
index 0000000..c483c23
--- /dev/null
+++ b/starter_templates/java/pom.xml
@@ -0,0 +1,52 @@
+
+
+ 4.0.0
+
+ io.codecrafters
+ build-your-own-sqlite
+ 1.0
+
+
+ 21
+ 21
+ UTF-8
+ 21
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+ java_sqlite
+
+ jar-with-dependencies
+
+ false
+
+
+ true
+
+ Main
+
+
+ ${dir}
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/starter_templates/java/src/main/java/Main.java b/starter_templates/java/src/main/java/Main.java
new file mode 100644
index 0000000..e4d6fe7
--- /dev/null
+++ b/starter_templates/java/src/main/java/Main.java
@@ -0,0 +1,38 @@
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+public class Main {
+ public static void main(String[] args){
+ if (args.length < 2) {
+ System.out.println("Missing and ");
+ return;
+ }
+
+ String databaseFilePath = args[0];
+ String command = args[1];
+
+ switch (command) {
+ case ".dbinfo" -> {
+ try {
+ byte[] header = Files.readAllBytes(Path.of(databaseFilePath));
+
+ // The page size is stored at the 16th byte offset, using 2 bytes in big-endian order.
+ // '& 0xFFFF' is used to convert the signed short to an unsigned int.
+ int pageSize = ByteBuffer.wrap(header).order(ByteOrder.BIG_ENDIAN).position(16).getShort() & 0xFFFF;
+
+ // You can use print statements as follows for debugging, they'll be visible when running tests.
+ System.out.println("Logs from your program will appear here!");
+
+ // Uncomment this block to pass the first stage
+ // System.out.println("database page size: " + pageSize);
+ } catch (IOException e) {
+ System.out.println("Error reading file: " + e.getMessage());
+ }
+ }
+ default -> System.out.println("Missing or invalid command passed: " + command);
+ }
+ }
+}
diff --git a/starter_templates/java/your_sqlite3.sh b/starter_templates/java/your_sqlite3.sh
new file mode 100755
index 0000000..c0d5216
--- /dev/null
+++ b/starter_templates/java/your_sqlite3.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+#
+# DON'T EDIT THIS!
+#
+# CodeCrafters uses this file to test your code. Don't make any changes here!
+#
+# DON'T EDIT THIS!
+set -e
+mvn -B --quiet package -Ddir=/tmp/codecrafters-sqlite-target
+exec java -jar /tmp/codecrafters-sqlite-target/java_sqlite.jar "$@"
\ No newline at end of file
diff --git a/starter_templates/javascript/app/main.js b/starter_templates/javascript/app/main.js
index 5fcdd28..4e5b751 100644
--- a/starter_templates/javascript/app/main.js
+++ b/starter_templates/javascript/app/main.js
@@ -9,7 +9,7 @@ if (command === ".dbinfo") {
const { buffer } = await databaseFileHandler.read({
length: 100,
position: 0,
- buffer: Buffer.alloc(100)
+ buffer: Buffer.alloc(100),
});
// You can use print statements as follows for debugging, they'll be visible when running tests.