Skip to content

Commit 32fd37f

Browse files
authored
Merge pull request #136 from bolivier/bolivier/add-clojure
Add Clojure
2 parents 25d07ca + 4b077b4 commit 32fd37f

File tree

33 files changed

+633
-0
lines changed

33 files changed

+633
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/sh
2+
#
3+
# This script is used to compile your program on CodeCrafters
4+
#
5+
# This runs before .codecrafters/run.sh
6+
#
7+
# Learn more: https://codecrafters.io/program-interface
8+
9+
set -e # Exit on failure
10+
11+
clj -T:build
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/sh
2+
#
3+
# This script is used to run your program on CodeCrafters
4+
#
5+
# This runs after .codecrafters/compile.sh
6+
#
7+
# Learn more: https://codecrafters.io/program-interface
8+
9+
set -e # Exit on failure
10+
11+
exec java -jar /tmp/codecrafters-build-sqlite-clojure/target.jar "$@"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Database files used for testing
2+
*.db
3+
4+
pom.xml
5+
pom.xml.asc
6+
*.jar
7+
*.class
8+
/lib/
9+
/classes/
10+
/target/
11+
/checkouts/
12+
.lein-deps-sum
13+
.lein-repl-history
14+
.lein-plugins/
15+
.lein-failures
16+
.nrepl-port
17+
.cpcache/
18+
deps/
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
![progress-banner](https://codecrafters.io/landing/images/default_progress_banners/sqlite.png)
2+
3+
This is a starting point for Clojure solutions to the
4+
["Build Your Own SQLite" Challenge](https://codecrafters.io/challenges/sqlite).
5+
6+
In this challenge, you'll build a barebones SQLite implementation that supports
7+
basic SQL queries like `SELECT`. Along the way we'll learn about
8+
[SQLite's file format](https://www.sqlite.org/fileformat.html), how indexed data
9+
is
10+
[stored in B-trees](https://jvns.ca/blog/2014/10/02/how-does-sqlite-work-part-2-btrees/)
11+
and more.
12+
13+
**Note**: If you're viewing this repo on GitHub, head over to
14+
[codecrafters.io](https://codecrafters.io) to try the challenge.
15+
16+
# Passing the first stage
17+
18+
The entry point for your SQLite implementation is in `src/sqlite/core.clj`.
19+
Study and uncomment the relevant code, and push your changes to pass the first
20+
stage:
21+
22+
```sh
23+
git commit -am "pass 1st stage" # any msg
24+
git push origin master
25+
```
26+
27+
Time to move on to the next stage!
28+
29+
# Stage 2 & beyond
30+
31+
Note: This section is for stages 2 and beyond.
32+
33+
1. Ensure you have `clj` installed locally
34+
1. Run `./your_program.sh` to run your program, which is implemented in
35+
`src/sqlite/core.clj`.
36+
1. Commit your changes and run `git push origin master` to submit your solution
37+
to CodeCrafters. Test output will be streamed to your terminal.
38+
39+
# Sample Databases
40+
41+
To make it easy to test queries locally, we've added a sample database in the
42+
root of this repository: `sample.db`.
43+
44+
This contains two tables: `apples` & `oranges`. You can use this to test your
45+
implementation for the first 6 stages.
46+
47+
You can explore this database by running queries against it like this:
48+
49+
```sh
50+
$ sqlite3 sample.db "select id, name from apples"
51+
1|Granny Smith
52+
2|Fuji
53+
3|Honeycrisp
54+
4|Golden Delicious
55+
```
56+
57+
There are two other databases that you can use:
58+
59+
1. `superheroes.db`:
60+
- This is a small version of the test database used in the table-scan stage.
61+
- It contains one table: `superheroes`.
62+
- It is ~1MB in size.
63+
1. `companies.db`:
64+
- This is a small version of the test database used in the index-scan stage.
65+
- It contains one table: `companies`, and one index: `idx_companies_country`
66+
- It is ~7MB in size.
67+
68+
These aren't included in the repository because they're large in size. You can
69+
download them by running this script:
70+
71+
```sh
72+
./download_sample_databases.sh
73+
```
74+
75+
If the script doesn't work for some reason, you can download the databases
76+
directly from
77+
[codecrafters-io/sample-sqlite-databases](https://github.com/codecrafters-io/sample-sqlite-databases).
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
(ns build
2+
(:gen-class)
3+
(:require [clojure.tools.build.api :as b]))
4+
5+
(def lib 'io.codecrafters.sqlite)
6+
(def class-dir "/tmp/codecrafters-build-sqlite-clojure/classes")
7+
(def basis (b/create-basis {:project "deps.edn"}))
8+
(def uber-file "/tmp/codecrafters-build-sqlite-clojure/target.jar")
9+
10+
(defn clean [_] (b/delete {:path "/tmp/codecrafters-build-sqlite-clojure"}))
11+
12+
(defn uber
13+
[_]
14+
(clean nil)
15+
(b/copy-dir {:src-dirs ["src"], :target-dir class-dir})
16+
(b/compile-clj
17+
{:basis basis, :ns-compile '[sqlite.core], :class-dir class-dir})
18+
(b/uber {:class-dir class-dir,
19+
:uber-file uber-file,
20+
:basis basis,
21+
:main 'sqlite.core}))
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Set this to true if you want debug logs.
2+
#
3+
# These can be VERY verbose, so we suggest turning them off
4+
# unless you really need them.
5+
debug: false
6+
7+
# Use this to change the Clojure version used to run your code
8+
# on Codecrafters.
9+
#
10+
# Available versions: clojure-1.12.0
11+
language_pack: clojure-1.12.0

compiled_starters/clojure/deps.edn

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
:paths ["src"]
3+
4+
:deps {
5+
org.clojure/clojure {:mvn/version "1.12.0"}
6+
org.clojure/tools.cli {:mvn/version "1.1.230"}
7+
}
8+
9+
:aliases {
10+
:build {
11+
:extra-deps {io.github.clojure/tools.build {:mvn/version "0.10.9"}}
12+
:exec-fn build/uber
13+
}
14+
}
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/bin/sh
2+
3+
echo "Downloading superheroes.db: ~1MB (used in stage 7)"
4+
curl -Lo superheroes.db https://raw.githubusercontent.com/codecrafters-io/sample-sqlite-databases/master/superheroes.db
5+
6+
echo "Downloading companies.db: ~7MB (used in stage 8)"
7+
curl -Lo companies.db https://raw.githubusercontent.com/codecrafters-io/sample-sqlite-databases/master/companies.db
8+
9+
echo "Sample databases downloaded."
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
(ns sqlite.core
2+
(:gen-class)
3+
(:require [clojure.java.io :as io]))
4+
5+
(defn lazy-byte-seq [filepath]
6+
(let [is (io/input-stream filepath)
7+
step (fn step [input-stream]
8+
(lazy-seq (let [byte-val (.read input-stream)]
9+
(when (not= byte-val -1)
10+
(cons byte-val (step input-stream))))))]
11+
(step is)))
12+
13+
(defn bytes-to-int [bytes]
14+
(reduce (fn [acc b] (+ (* acc 256) b))
15+
0
16+
bytes))
17+
18+
(defn -main [& args]
19+
;; You can use print statements as follows for debugging, they'll be
20+
;; visible when running tests.
21+
(println "Logs from your program will appear here!")
22+
;; Uncomment this block to pass the first stage
23+
;; (let [command (second args)]
24+
;; (case command
25+
;; ".dbinfo"
26+
;; (let [db-file-path (first args)
27+
;; contents (lazy-byte-seq db-file-path)
28+
;; page-size (bytes-to-int (take 2 (drop 16 contents)))]
29+
;; (println (str "database page size: " page-size)))))
30+
)

0 commit comments

Comments
 (0)