Skip to content

Commit ecbbb52

Browse files
init
0 parents  commit ecbbb52

38 files changed

+2588
-0
lines changed

.gitignore

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# IDE's
4+
**/.atom/
5+
**/.idea/
6+
**/nbproject/
7+
**/.vscode/
8+
9+
# Docker
10+
# /*.dockerfile
11+
# /*.yml
12+
13+
# PIP
14+
build/*
15+
dist/*
16+
venv/*
17+
18+
# Misc
19+
**/__pycache__
20+
**/.DS_Store
21+
**/*.egg-info
22+
**/desktop.ini
23+
**/*.log*
24+
**/*.sql
25+
**/*.db

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT LICENSE
2+
3+
COPYRIGHT (R) 2025 ARNELIFY. AUTHOR: TARON SARKISYAN
4+
5+
PERMISSION IS HEREBY GRANTED, FREE OF CHARGE, TO ANY PERSON OBTAINING A COPY
6+
OF THIS SOFTWARE AND ASSOCIATED DOCUMENTATION FILES (THE "SOFTWARE"), TO DEAL
7+
IN THE SOFTWARE WITHOUT RESTRICTION, INCLUDING WITHOUT LIMITATION THE RIGHTS
8+
TO USE, COPY, MODIFY, MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL
9+
COPIES OF THE SOFTWARE, AND TO PERMIT PERSONS TO WHOM THE SOFTWARE IS
10+
FURNISHED TO DO SO, SUBJECT TO THE FOLLOWING CONDITIONS:
11+
12+
THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN ALL
13+
COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
recursive-include arnelify_orm/cpp *.cpp *.hpp

Makefile

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Boot Makefile
2+
# See https://www.gnu.org/software/make/manual/make.html for more about make.
3+
4+
# ENGINE
5+
ENGINE = g++
6+
ENGINE_FLAGS = -std=c++2b
7+
8+
# PATH
9+
PATH_BIN = $(CURDIR)/tests/bin/index.bin
10+
PATH_SRC = $(CURDIR)/tests/index.py
11+
12+
# INC
13+
INC_CPP = -I $(CURDIR)/src/cpp
14+
INC_INCLUDE = -L /usr/include
15+
INC_JSONCPP = -I /usr/include/jsoncpp/json
16+
INC = ${INC_CPP} ${INC_INCLUDE} ${INC_JSONCPP}
17+
18+
# LINK
19+
LINK_JSONCPP = -ljsoncpp
20+
LINK_ZLIB = -lz
21+
LINK = ${LINK_JSONCPP} ${LINK_ZLIB}
22+
23+
# PYTHON
24+
PYTHON = venv/bin/python
25+
PYTHON_FLAGS = -m
26+
PYPI = venv/bin/pip
27+
28+
# NUITKA
29+
NUITKA = venv/bin/nuitka
30+
NUITKA_FLAGS = --standalone --onefile
31+
32+
# SCRIPTS
33+
install:
34+
clear && find . -type d -name '__pycache__' -exec rm -r {} +
35+
rm -rf build && rm -rf dist && rm -rf venv
36+
python ${PYTHON_FLAGS} venv venv
37+
${PYPI} install -r requirements.txt
38+
39+
build:
40+
clear && rm -rf build/* && rm -rf dist/*
41+
${PYTHON} setup.py sdist bdist_wheel --plat-name=manylinux2014_x86_64
42+
${PYTHON} ${PYTHON_FLAGS} index
43+
44+
test:
45+
clear && mkdir -p tests/bin && rm -rf tests/bin/*
46+
${PYTHON} ${PYTHON_FLAGS} tests.index
47+
48+
test_nuitka:
49+
clear && mkdir -p tests/bin && rm -rf tests/bin/*
50+
${NUITKA} ${NUITKA_FLAGS} --output-dir=tests/bin ${PATH_SRC} && clear
51+
${PATH_BIN}
52+
53+
.PHONY: build test

README.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<img src="https://static.wikia.nocookie.net/arnelify/images/c/c8/Arnelify-logo-2024.png/revision/latest?cb=20240701012515" style="width:336px;" alt="Arnelify Logo" />
2+
3+
![Arnelify ORM for Python](https://img.shields.io/badge/Arnelify%20ORM%20for%20Python-0.6.1-yellow) ![C++](https://img.shields.io/badge/C++-2b-red) ![G++](https://img.shields.io/badge/G++-14.2.0-blue) ![Python](https://img.shields.io/badge/Python-3.11.2-blue) ![Nuitka](https://img.shields.io/badge/Nuitka-2.6.4-blue)
4+
5+
## 🚀 About
6+
**Arnelify® ORM for Python** - is a minimalistic dynamic library which is an ORM written in C and C++.
7+
8+
## 📋 Minimal Requirements
9+
> Important: It's strongly recommended to use in a container that has been built from the gcc v14.2.0 image.
10+
* CPU: Apple M1 / Intel Core i7 / AMD Ryzen 7
11+
* OS: Debian 11 / MacOS 15 / Windows 10 with <a href="https://learn.microsoft.com/en-us/windows/wsl/install">WSL2</a>.
12+
* RAM: 4 GB
13+
14+
## 📦 Installation
15+
Installing via pip:
16+
```
17+
pip install arnelify-orm
18+
```
19+
## 🎉 Usage
20+
Install dependencies:
21+
```
22+
make install
23+
```
24+
Compile library:
25+
```
26+
make build
27+
```
28+
Compile & Run test:
29+
```
30+
make test_nuitka
31+
```
32+
Run test:
33+
```
34+
make test
35+
```
36+
## 📚 Code Examples
37+
Configure the C/C++ IntelliSense plugin for VSCode (optional).
38+
```
39+
Clang_format_fallback = Google
40+
```
41+
42+
IncludePath for VSCode (optional):
43+
```
44+
"includePath": [
45+
"/opt/homebrew/opt/jsoncpp/include/json",
46+
"/opt/homebrew/opt/mysql-client/include"
47+
],
48+
```
49+
You can find code examples <a href="https://github.com/arnelify/arnelify-orm-python/blob/main/tests/index.py">here</a>.
50+
51+
## ⚖️ MIT License
52+
This software is licensed under the <a href="https://github.com/arnelify/arnelify-orm-python/blob/main/LICENSE">MIT License</a>. The original author's name, logo, and the original name of the software must be included in all copies or substantial portions of the software.
53+
54+
## 🛠️ Contributing
55+
Join us to help improve this software, fix bugs or implement new functionality. Active participation will help keep the software up-to-date, reliable, and aligned with the needs of its users.
56+
57+
## ⭐ Release Notes
58+
Version 0.6.1 - Minimalistic dynamic library
59+
60+
We are excited to introduce the Arnelify ORM dynamic library for Python! Please note that this version is raw and still in active development.
61+
62+
Change log:
63+
64+
* Minimalistic dynamic library
65+
* NodeJS (Bun) addon
66+
* FFI Support
67+
68+
Please use this version with caution, as it may contain bugs and unfinished features. We are actively working on improving and expanding the ORM's capabilities, and we welcome your feedback and suggestions.
69+
70+
## 🔗 Mentioned
71+
72+
* <a href="https://github.com/arnelify/arnelify-pod-cpp">Arnelify POD for C++</a>
73+
* <a href="https://github.com/arnelify/arnelify-pod-python">Arnelify POD for Python</a>
74+
* <a href="https://github.com/arnelify/arnelify-pod-node">Arnelify POD for NodeJS</a>
75+
* <a href="https://github.com/arnelify/arnelify-react-native">Arnelify React Native</a>

arnelify_orm/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .index import ArnelifyORM

arnelify_orm/cpp/addon.cpp

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#ifndef ARNELIFY_ORM_ADDON_CPP
2+
#define ARNELIFY_ORM_ADDON_CPP
3+
4+
#include <future>
5+
#include <iostream>
6+
#include <thread>
7+
8+
#include "json.h"
9+
#include "napi.h"
10+
11+
#include "index.cpp"
12+
13+
ArnelifyORM* orm = nullptr;
14+
15+
Napi::Value orm_create(const Napi::CallbackInfo& args) {
16+
Napi::Env env = args.Env();
17+
if (args.Length() < 1 || !args[0].IsString()) {
18+
Napi::TypeError::New(env,
19+
"[Arnelify ORM]: C++ error: Expected optsWrapped.")
20+
.ThrowAsJavaScriptException();
21+
return env.Undefined();
22+
}
23+
24+
Napi::String optsWrapped = args[0].As<Napi::String>();
25+
std::string serialized = optsWrapped.Utf8Value();
26+
27+
Json::Value json;
28+
Json::CharReaderBuilder reader;
29+
std::string errors;
30+
31+
std::istringstream iss(serialized);
32+
if (!Json::parseFromStream(reader, iss, &json, &errors)) {
33+
std::cout << "[Arnelify ORM]: C++ error: Invalid cOpts." << std::endl;
34+
exit(1);
35+
}
36+
37+
const bool hasDriver =
38+
json.isMember("ORM_DRIVER") && json["ORM_DRIVER"].isString();
39+
if (!hasDriver) {
40+
std::cout << "[Arnelify ORM]: C++ error: 'ORM_DRIVER' is missing."
41+
<< std::endl;
42+
exit(1);
43+
}
44+
45+
const bool hasHost = json.isMember("ORM_HOST") && json["ORM_HOST"].isString();
46+
if (!hasHost) {
47+
std::cout << "[Arnelify ORM]: C++ error: 'ORM_HOST' is missing."
48+
<< std::endl;
49+
exit(1);
50+
}
51+
52+
const bool hasName = json.isMember("ORM_NAME") && json["ORM_NAME"].isString();
53+
if (!hasName) {
54+
std::cout << "[Arnelify ORM]: C++ error: 'ORM_NAME' is missing."
55+
<< std::endl;
56+
exit(1);
57+
}
58+
59+
const bool hasUser = json.isMember("ORM_USER") && json["ORM_USER"].isString();
60+
if (!hasUser) {
61+
std::cout << "[Arnelify ORM]: C++ error: 'ORM_USER' is missing."
62+
<< std::endl;
63+
exit(1);
64+
}
65+
66+
const bool hasPass = json.isMember("ORM_PASS") && json["ORM_PASS"].isString();
67+
if (!hasPass) {
68+
std::cout << "[Arnelify ORM]: C++ error: 'ORM_PASS' is missing."
69+
<< std::endl;
70+
exit(1);
71+
}
72+
73+
const bool hasPort = json.isMember("ORM_PORT") && json["ORM_PORT"].isInt();
74+
if (!hasPort) {
75+
std::cout << "[Arnelify ORM]: C++ error: 'ORM_PORT' is missing."
76+
<< std::endl;
77+
exit(1);
78+
}
79+
80+
ArnelifyORMOpts opts(json["ORM_DRIVER"].asString(),
81+
json["ORM_HOST"].asString(), json["ORM_NAME"].asString(),
82+
json["ORM_USER"].asString(), json["ORM_PASS"].asString(),
83+
json["ORM_PORT"].asInt());
84+
85+
orm = new ArnelifyORM(opts);
86+
87+
return env.Undefined();
88+
}
89+
90+
Napi::Value orm_destroy(const Napi::CallbackInfo& args) {
91+
Napi::Env env = args.Env();
92+
93+
delete orm;
94+
orm = nullptr;
95+
return env.Undefined();
96+
}
97+
98+
Napi::Value orm_exec(const Napi::CallbackInfo& info) {
99+
Napi::Env env = info.Env();
100+
if (!info.Length() || !info[0].IsString()) {
101+
Napi::TypeError::New(env, "[Arnelify ORM]: C++ error: query is missing.")
102+
.ThrowAsJavaScriptException();
103+
return env.Undefined();
104+
}
105+
106+
if (2 > info.Length() || !info[1].IsString()) {
107+
Napi::TypeError::New(env, "[Arnelify ORM]: C++ error: bindings is missing.")
108+
.ThrowAsJavaScriptException();
109+
return env.Undefined();
110+
}
111+
112+
const std::string query = info[0].As<Napi::String>();
113+
const std::string serialized = info[1].As<Napi::String>();
114+
std::vector<std::string> bindings;
115+
116+
Json::Value deserialized;
117+
Json::CharReaderBuilder reader;
118+
std::string errors;
119+
120+
std::istringstream iss(serialized);
121+
if (!Json::parseFromStream(reader, iss, &deserialized, &errors)) {
122+
std::cout << "[Arnelify ORM]: C++ error: bindings must be a valid JSON."
123+
<< std::endl;
124+
exit(1);
125+
}
126+
127+
for (int i = 0; deserialized.size() > i; ++i) {
128+
const Json::Value& value = deserialized[i];
129+
bindings.emplace_back(value.asString());
130+
}
131+
132+
ArnelifyORMRes res = orm->exec(query, bindings);
133+
Json::Value json = orm->toJson(res);
134+
135+
Json::StreamWriterBuilder writer;
136+
writer["indentation"] = "";
137+
writer["emitUTF8"] = true;
138+
139+
const std::string out = Json::writeString(writer, json);
140+
return Napi::String::New(env, out);
141+
}
142+
143+
Napi::Object Init(Napi::Env env, Napi::Object exports) {
144+
exports.Set("orm_create", Napi::Function::New(env, orm_create));
145+
exports.Set("orm_destroy", Napi::Function::New(env, orm_destroy));
146+
exports.Set("orm_exec", Napi::Function::New(env, orm_exec));
147+
return exports;
148+
}
149+
150+
NODE_API_MODULE(ARNELIFY_ORM, Init)
151+
152+
#endif
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#ifndef ARNELIFY_ORM_OPTS_HPP
2+
#define ARNELIFY_ORM_OPTS_HPP
3+
4+
#include <iostream>
5+
6+
struct ArnelifyORMOpts final {
7+
const std::string ORM_DRIVER;
8+
const std::string ORM_HOST;
9+
const std::string ORM_NAME;
10+
const std::string ORM_USER;
11+
const std::string ORM_PASS;
12+
const int ORM_PORT;
13+
14+
ArnelifyORMOpts(const std::string d, const std::string h,
15+
const std::string n, const std::string u,
16+
const std::string pwd, const int p)
17+
: ORM_DRIVER(d),
18+
ORM_HOST(h),
19+
ORM_NAME(n),
20+
ORM_USER(u),
21+
ORM_PASS(pwd),
22+
ORM_PORT(p) {};
23+
};
24+
25+
#endif

arnelify_orm/cpp/contracts/res.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#ifndef ARNELIFY_ORM_RES_HPP
2+
#define ARNELIFY_ORM_RES_HPP
3+
4+
#include <iostream>
5+
#include <map>
6+
#include <variant>
7+
8+
using ArnelifyORMRow = std::map<std::string, std::variant<std::nullptr_t, std::string>>;
9+
using ArnelifyORMRes = std::vector<ArnelifyORMRow>;
10+
11+
#endif

0 commit comments

Comments
 (0)