Add src/sql/
The src/sql/ directory contains SQL files for creating a SQL database containing The Qur'an in four languages: Arabic, English, Portuguese, and Farsi.
This commit is contained in:
parent
5d3c3cc5fc
commit
d1512bfc3a
465 changed files with 25706 additions and 59 deletions
148
README.md
148
README.md
|
@ -1,28 +1,26 @@
|
|||
# The Qur'an
|
||||
|
||||
This repository contains the holy book, The Qur'an, in its original Arabic and as translations
|
||||
in English, Farsi, and Portuguese - all of which are stored in the JSON format. It is hoped that
|
||||
through this repository those working with The Qur'an in the context of software will find a resource
|
||||
that's helpful to their work.
|
||||
in English, Farsi, and Portuguese. The contents are made available in JSON, and SQL files.
|
||||
|
||||
## Layout
|
||||
## `src/json/` directory
|
||||
|
||||
### The `src/` directory
|
||||
This section covers the JSON files. Keep scrolling for the SQL section.
|
||||
|
||||
* The [src/arabic/](src/arabic/) directory contains The Qur'an in its original Arabic.
|
||||
* The [src/json/ar/](src/json/ar/) directory contains The Qur'an in its original Arabic.
|
||||
|
||||
* The [src/english/](src/english/) directory contains an English translation of The Qur'an.
|
||||
* The [src/json/en/](src/json/en/) directory contains an English translation of The Qur'an.
|
||||
|
||||
* The [src/farsi/](src/farsi/) directory contains a Farsi translation of The Qur'an.
|
||||
* The [src/json/fa/](src/json/fa/) directory contains a Farsi translation of The Qur'an.
|
||||
|
||||
* The [src/portuguese/](src/portuguese/) directory contains a Portuguese translation of The Qur'an.
|
||||
* The [src/json/pt/](src/json/pt/) directory contains a Portuguese translation of The Qur'an.
|
||||
|
||||
#### Arabic
|
||||
### Arabic
|
||||
|
||||
* [src/arabic/](src/arabic/)
|
||||
* [src/json/ar/](src/json/ar/)
|
||||
|
||||
Each JSON file represents a chapter, or surah - in its original Arabic.
|
||||
For example, [src/arabic/1.json](src/arabic/1.json) contains Al-Fatihah.
|
||||
For example, [src/json/ar/1.json](src/json/ar/1.json) contains Al-Fatihah.
|
||||
The structure of the file can be described as an array of arrays, with
|
||||
each array representing a verse, or ayah.
|
||||
For example:
|
||||
|
@ -45,14 +43,14 @@ For example:
|
|||
]
|
||||
```
|
||||
|
||||
#### English
|
||||
### English
|
||||
|
||||
* [src/english/](src/english)
|
||||
* [src/json/en/](src/json/en/)
|
||||
|
||||
Each JSON file represents a chapter, or surah - as an English translation.
|
||||
The structure of the file can be described as an array of arrays,
|
||||
with each array representing a verse, or ayah. For example, consider
|
||||
the English translation of Al-Fatihah ([src/english/1.json](src/english/1.json)):
|
||||
the English translation of Al-Fatihah ([src/json/en/1.json](src/json/en/1.json)):
|
||||
|
||||
```
|
||||
[
|
||||
|
@ -87,12 +85,12 @@ the English translation of Al-Fatihah ([src/english/1.json](src/english/1.json))
|
|||
]
|
||||
```
|
||||
|
||||
#### Farsi
|
||||
### Farsi
|
||||
|
||||
* [src/farsi/](src/farsi/)
|
||||
* [src/json/fa/](src/json/fa/)
|
||||
|
||||
Each JSON file represents a chapter, or surah - as a Farsi translation.
|
||||
For example, [src/farsi/1.json](src/farsi/1.json) contains Al-Fatihah.
|
||||
For example, [src/json/fa/1.json](src/json/fa/1.json) contains Al-Fatihah.
|
||||
The structure of the file can be described as an array of arrays, with
|
||||
each array representing a verse, or ayah.
|
||||
For example:
|
||||
|
@ -115,12 +113,12 @@ For example:
|
|||
]
|
||||
```
|
||||
|
||||
#### Portuguese
|
||||
### Portuguese
|
||||
|
||||
* [src/portuguese/](src/portuguese/)
|
||||
* [src/json/pt/](src/json/pt/)
|
||||
|
||||
Each JSON file represents a chapter, or surah - as a Portuguese translation.
|
||||
For example, [src/portuguese/1.json](src/portuguese/1.json) contains Al-Fatihah.
|
||||
For example, [src/pt/1.json](src/json/pt/1.json) contains Al-Fatihah.
|
||||
The structure of the file can be described as an array of arrays, with each array
|
||||
representing a verse, or ayah.
|
||||
For example:
|
||||
|
@ -143,31 +141,125 @@ For example:
|
|||
]
|
||||
```
|
||||
|
||||
## `src/sql/` directory
|
||||
|
||||
This section covers the SQL files.
|
||||
|
||||
* The [src/sql/schema.sql](src/sql/schema.sql) defines the schema of the database. <br>
|
||||
The schema is composed of three tables: `qurans`, `chapters`, and `verses`.
|
||||
|
||||
* The [src/sql/seed.sql](src/sql/seed.sql) populates the contents of the database. <br>
|
||||
The languages included are Arabic, English, Farsi, and Portuguese.
|
||||
|
||||
### SQLite3 example
|
||||
|
||||
The example demonstrates how the SQL files mentioned above can be used to create a
|
||||
fully populated database, and then how to query the database. It is assumed that the
|
||||
repository has been cloned or downloaded (see below), and that "sqlite3" is started
|
||||
from the root of the repository.
|
||||
|
||||
**1. $HOME/.sqliterc**
|
||||
|
||||
For identical results, it is recommended that the `$HOME/.sqlitrc` file has the following
|
||||
contents:
|
||||
|
||||
```
|
||||
pragma FOREIGN_KEYS = on;
|
||||
.headers on
|
||||
.mode column
|
||||
```
|
||||
|
||||
**2. Execute `src/sql/schema.sql`**
|
||||
|
||||
Start SQLite3 from the command line, and then execute `.read src/sql/schema.sql`:
|
||||
|
||||
```
|
||||
$ sqlite3
|
||||
SQLite version 3.39.0 2022-06-25 14:57:57
|
||||
Enter ".help" for usage hints.
|
||||
Connected to a transient in-memory database.
|
||||
Use ".open FILENAME" to reopen on a persistent database.
|
||||
sqlite> .read src/sql/schema.sql
|
||||
sqlite>
|
||||
```
|
||||
|
||||
**3. Execute `src/sql/seed.sql`**
|
||||
|
||||
Within the same sqlite session, execute `.read src/sql/seed.sql`:
|
||||
|
||||
```
|
||||
sqlite> .read src/sql/seed.sql
|
||||
sqlite>
|
||||
```
|
||||
|
||||
**4. Query the database**
|
||||
|
||||
After steps two and three, the database is fully populated and exists in memory / RAM. <br>
|
||||
We can now query the database and its contents. The SQL query we will execute fetches the
|
||||
contents of chapter 112 in the English locale (i.e: `en`):
|
||||
|
||||
```sql
|
||||
SELECT qurans.locale,
|
||||
chapters.number as chapter_number,
|
||||
verses.number as verse_number,
|
||||
verses.content from verses
|
||||
INNER JOIN qurans ON qurans.id = verses.quran_id
|
||||
INNER JOIN chapters ON chapters.id = verses.chapter_id
|
||||
WHERE qurans.locale = "en" AND chapters.number = 112;
|
||||
```
|
||||
|
||||
The output should look like this:
|
||||
|
||||
```
|
||||
sqlite> SELECT qurans.locale,
|
||||
...> chapters.number as chapter_number,
|
||||
...> verses.number as verse_number,
|
||||
...> verses.content from verses
|
||||
...> INNER JOIN qurans ON qurans.id = verses.quran_id
|
||||
...> INNER JOIN chapters ON chapters.id = verses.chapter_id
|
||||
...> WHERE qurans.locale = "en" AND chapters.number = 112;
|
||||
locale chapter_number verse_number content
|
||||
------ -------------- ------------ -----------------------------------------------------
|
||||
en 112 1 Say, ˹O Prophet,˺ “He is Allah—One ˹and Indivisible˺;
|
||||
en 112 2 Allah—the Sustainer ˹needed by all˺.
|
||||
en 112 3 He has never had offspring, nor was He born.
|
||||
en 112 4 And there is none comparable to Him.”
|
||||
```
|
||||
|
||||
## The `bin/` directory
|
||||
|
||||
The [bin/](bin/) directory contains four scripts that generate the
|
||||
The [bin/](bin/) directory contains scripts that generate the
|
||||
contents of the [src/](src/) directory:
|
||||
|
||||
* [bin/pull-arabic](bin/pull-arabic) <br>
|
||||
This script is responsible for populating [src/arabic/](src/arabic/).
|
||||
This script is responsible for populating [src/json/ar/](src/json/ar/).
|
||||
|
||||
* [bin/pull-english](bin/pull-english) <br>
|
||||
This script is responsible for populating [src/english/](src/english/).
|
||||
This script is responsible for populating [src/json/en/](src/json/en/).
|
||||
|
||||
* [bin/pull-farsi](bin/pull-farsi) <br>
|
||||
This script is responsible for populating [src/farsi/](src/farsi/).
|
||||
This script is responsible for populating [src/json/fa/](src/json/fa/).
|
||||
|
||||
* [bin/pull-portuguese](bin/pull-portuguese) <br>
|
||||
This script is responsible for populating [src/portuguese/](src/portuguese/).
|
||||
This script is responsible for populating [src/json/pt/](src/json/pt/).
|
||||
|
||||
**Note**
|
||||
* [bin/create-sql-seed-file](bin/create-sql-seed-file) <br>
|
||||
This script creates [src/sql/seed.sql](src/sql/seed.sql), and uses the contents of
|
||||
[src/json/](src/json/) to do so.
|
||||
|
||||
**Note #1**
|
||||
|
||||
By default it is not neccessary to run these scripts because the contents of `src/` is included in
|
||||
the repository already.
|
||||
|
||||
|
||||
**Note #2**
|
||||
|
||||
The scripts are written in [Ruby v3.1.0+](https://www.ruby-lang.org). <br>
|
||||
The ["pull-english"](bin/pull-english), ["pull-farsi"](bin/pull-farsi) and
|
||||
["pull-portuguese"](bin/pull-portuguese) scripts depend on the ["pull-arabic"](bin/pull-arabic)
|
||||
script being run first. The script dependencies can be installed by
|
||||
running `gem install -g gem.deps.rb` from the root of the repository.
|
||||
|
||||
## Download
|
||||
|
||||
For those of you who don't have access to, or know how to use "git",
|
||||
|
|
60
bin/create-sql-seed-file
Executable file
60
bin/create-sql-seed-file
Executable file
|
@ -0,0 +1,60 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
require "json"
|
||||
require "erb"
|
||||
|
||||
module SQLUtils
|
||||
module_function
|
||||
def escape(str)
|
||||
char = "'"
|
||||
char + str.gsub(char, char * 2) + char
|
||||
end
|
||||
end
|
||||
|
||||
class Language
|
||||
attr_reader :locale
|
||||
|
||||
def initialize(locale)
|
||||
@locale = locale
|
||||
end
|
||||
|
||||
def chapters
|
||||
Dir.glob(File.join(
|
||||
__dir__, "..", "src",
|
||||
"json", @locale, "*.json"
|
||||
)).map { Chapter.new(_1) }.sort_by(&:number)
|
||||
end
|
||||
end
|
||||
|
||||
class Chapter
|
||||
def initialize(path)
|
||||
@path = path
|
||||
end
|
||||
|
||||
def number
|
||||
File.basename(@path, '.json').to_i
|
||||
end
|
||||
|
||||
def verses
|
||||
JSON.parse(File.read(@path)).map { Verse.new(*_1) }
|
||||
end
|
||||
end
|
||||
|
||||
class Verse
|
||||
attr_reader :number, :content
|
||||
|
||||
def initialize(number, content)
|
||||
@number = number
|
||||
@content = content
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
base_dir = File.join(__dir__, "..", "src", "sql")
|
||||
template = File.read File.join(base_dir, "seed.sql.erb")
|
||||
languages = %w(ar en pt fa).map { Language.new(_1) }
|
||||
result = ERB.new(template)
|
||||
.result_with_hash(chapter_id: 1, languages:)
|
||||
.each_line.map(&:strip)
|
||||
.reject(&:empty?).join($/)
|
||||
File.write File.join(base_dir, "seed.sql"), result
|
|
@ -6,7 +6,7 @@
|
|||
# is requested from the https://sacred-texts.com website.
|
||||
#
|
||||
# Each chapter is then saved in a JSON file, for example:
|
||||
# "src/arabic/<chapter_num>.json".
|
||||
# "src/ar/<chapter_num>.json".
|
||||
|
||||
##
|
||||
# Dependencies
|
||||
|
@ -19,7 +19,9 @@ require "paint"
|
|||
# Configuration variables.
|
||||
base_uri = "www.sacred-texts.com"
|
||||
path = "/isl/uq/%{htm_file}"
|
||||
dest_path = File.expand_path File.join(__dir__, "..", "src", "arabic", "%{chapter_num}.json")
|
||||
dest_path = File.join(
|
||||
__dir__, "..", "src", "json", "ar", "%{chapter_num}.json"
|
||||
)
|
||||
chapter_count = 114
|
||||
cool_off = 5
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# is requested from the https://quran.com website.
|
||||
#
|
||||
# Each chapter is then saved in a JSON file, for example:
|
||||
# "src/english/<chapter_num>.json"
|
||||
# "src/en/<chapter_num>.json"
|
||||
|
||||
##
|
||||
# Dependencies
|
||||
|
@ -19,8 +19,12 @@ require "paint"
|
|||
# Configuration variables.
|
||||
base_uri = "quran.com"
|
||||
path = "/%{chapter_num}/%{verse_num}"
|
||||
dest_path = File.expand_path File.join(__dir__, "..", "src", "english", "%{chapter_num}.json")
|
||||
arab_path = File.expand_path File.join(__dir__, "..", "src", "arabic", "%{chapter_num}.json")
|
||||
dest_path = File.join(
|
||||
__dir__, "..", "src", "json", "en", "%{chapter_num}.json"
|
||||
)
|
||||
arab_path = File.join(
|
||||
__dir__, "..", "src", "json", "ar", "%{chapter_num}.json"
|
||||
)
|
||||
chapter_count = 114
|
||||
cool_off = 5
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# is requested from the https://al-quran.cc website.
|
||||
#
|
||||
# Each chapter is then saved in a JSON file, for example:
|
||||
# "src/farsi/<chapter_num>.json"
|
||||
# "src/fa/<chapter_num>.json"
|
||||
|
||||
##
|
||||
# Dependencies
|
||||
|
@ -54,19 +54,11 @@ ch_names = %w[
|
|||
base_uri = "al-quran.cc"
|
||||
path = "/quran-translation/farsi/%{ch_name}/%{verse_num}.html"
|
||||
cool_off = 5
|
||||
arab_path = File.expand_path File.join(
|
||||
__dir__,
|
||||
"..",
|
||||
"src",
|
||||
"arabic",
|
||||
"%{chapter_num}.json"
|
||||
arab_path = File.join(
|
||||
__dir__, "..", "src", "json", "ar", "%{chapter_num}.json"
|
||||
)
|
||||
dest_path = File.expand_path File.join(
|
||||
__dir__,
|
||||
"..",
|
||||
"src",
|
||||
"farsi",
|
||||
"%{chapter_num}.json"
|
||||
dest_path = File.join(
|
||||
__dir__, "..", "src", "json", "fa", "%{chapter_num}.json"
|
||||
)
|
||||
|
||||
##
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# is requested from the https://al-quran.cc website.
|
||||
#
|
||||
# Each chapter is then saved in a JSON file, for example:
|
||||
# "src/portuguese/<chapter_num>.json"
|
||||
# "src/pt/<chapter_num>.json"
|
||||
|
||||
##
|
||||
# Dependencies
|
||||
|
@ -54,19 +54,11 @@ ch_names = %w[
|
|||
base_uri = "al-quran.cc"
|
||||
path = "/quran-translation/portuguese/%{ch_name}/%{verse_num}.html"
|
||||
cool_off = 5
|
||||
arab_path = File.expand_path File.join(
|
||||
__dir__,
|
||||
"..",
|
||||
"src",
|
||||
"arabic",
|
||||
"%{chapter_num}.json"
|
||||
arab_path = File.join(
|
||||
__dir__, "..", "src", "json", "ar", "%{chapter_num}.json"
|
||||
)
|
||||
dest_path = File.expand_path File.join(
|
||||
__dir__,
|
||||
"..",
|
||||
"src",
|
||||
"portuguese",
|
||||
"%{chapter_num}.json"
|
||||
dest_path = File.join(
|
||||
__dir__, "..", "src", "json", "pt", "%{chapter_num}.json"
|
||||
)
|
||||
|
||||
##
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue