Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
a799e5f
add benchmark to tests
TheMainMamad Apr 13, 2023
09e464f
add config files and handlers & setuptools
TheMainMamad Apr 14, 2023
aa14ce5
recode TupleGraph
MisanoGo Apr 14, 2023
ef95159
go run
MisanoGo Apr 14, 2023
3f3a317
Merge pull request #2 from MisanoGo/TupleGraphDict
MisanoGo Apr 14, 2023
efeb98f
dynamic count of test values generation
TheMainMamad Apr 14, 2023
aaa25e8
dynamic count of test values generation
TheMainMamad Apr 14, 2023
6e0f32d
fix bugs
MisanoGo Apr 14, 2023
7dce264
merge dev
TheMainMamad Apr 14, 2023
063eec0
code quering & fix bugs
MisanoGo Apr 15, 2023
5eac722
fix
MisanoGo Apr 15, 2023
fb64131
implement ORDER_BY
MisanoGo Apr 16, 2023
609760e
fix byg
MisanoGo Apr 16, 2023
0e7d63f
fix bugs
MisanoGo Apr 16, 2023
277e5e3
set Optional
MisanoGo Apr 16, 2023
79c357b
fix misstake
MisanoGo Apr 16, 2023
4174785
hora, Fix q.WHERE(q.<column> >20).ORDER_BY('<column>').all() bug)
MisanoGo Apr 16, 2023
11e8dfb
write a docs
MisanoGo Apr 16, 2023
435d741
add logs to .logs file
MisanoGo Apr 16, 2023
20f3872
set get_attr def
MisanoGo Apr 17, 2023
9be5a72
set get_attr & some hints
MisanoGo Apr 17, 2023
b7dc9fd
add numpy lib to requierds
MisanoGo Apr 17, 2023
96950b8
update flag
MisanoGo Apr 17, 2023
d781559
split tests
MisanoGo Apr 17, 2023
ea23319
fix bugs & solve DELELTE problem & indexing None and 0 objects
MisanoGo Apr 17, 2023
52d70f0
implement SELECT statament
MisanoGo Apr 17, 2023
bb0508b
TODO migrate
MisanoGo Apr 17, 2023
c85a654
set type hints
MisanoGo Apr 17, 2023
38aab47
update
MisanoGo Apr 17, 2023
1c51ef3
implement raw data
MisanoGo Apr 17, 2023
29d85f9
implement DBRead
MisanoGo Apr 17, 2023
b4d0800
set multi access
MisanoGo Apr 17, 2023
235b54a
fix bug & set uniqe & typing
MisanoGo Apr 18, 2023
3991e41
set add_op
MisanoGo Apr 18, 2023
12beb9c
delete __state, best code
MisanoGo Apr 18, 2023
df18c61
TODO
MisanoGo Apr 18, 2023
33a0543
TODO
MisanoGo Apr 18, 2023
5373e87
fire code
MisanoGo Apr 18, 2023
63052d5
rm tog.py & fire code
MisanoGo Apr 19, 2023
6565415
benchmark
MisanoGo Apr 19, 2023
f0cdaf6
fix bug
MisanoGo Apr 21, 2023
4bafe9b
update
MisanoGo Apr 22, 2023
1e2f9fc
update test
MisanoGo Apr 22, 2023
d589b9d
set auto ID setting
MisanoGo Apr 22, 2023
c698f0b
split box files, implement columns
MisanoGo Apr 23, 2023
f77030b
solve performance bug
MisanoGo Apr 23, 2023
c042d8d
add 10000
MisanoGo Apr 23, 2023
171f112
solve DELETE, id generator, bugs
MisanoGo Apr 24, 2023
bb54c55
split benchmark test, uncomment data, solve ID bug
MisanoGo Apr 24, 2023
6f30e12
.
MisanoGo Apr 24, 2023
767e994
add filter None objects method
MisanoGo Apr 25, 2023
e6cab02
clean code
MisanoGo Apr 25, 2023
6798e0a
clean code, make standard, rewrite ID and record access, change logic…
MisanoGo Apr 25, 2023
e0a2c28
update
MisanoGo Apr 25, 2023
7712c1f
change name of JsonQuery to FoxQuery, set Den methods name as lowercase
MisanoGo Apr 25, 2023
586dc50
fix
MisanoGo Apr 25, 2023
cc9dc0e
try
MisanoGo Apr 25, 2023
b5a2e96
define max,min,mean
MisanoGo Apr 25, 2023
7d7026d
bug
MisanoGo Apr 25, 2023
f1806e2
update
MisanoGo Apr 25, 2023
dfdfc83
update
MisanoGo Apr 25, 2023
6570160
add doc
MisanoGo Apr 25, 2023
8da428e
add doc
MisanoGo Apr 25, 2023
78b9c9d
develop box manager
MisanoGo Apr 26, 2023
01beefb
create empty docs
MisanoGo Apr 26, 2023
4021d00
update
MisanoGo Apr 26, 2023
0fcaa02
write doc & code filter
MisanoGo Apr 26, 2023
e6be884
write docs
MisanoGo Apr 26, 2023
aafb8f8
fix bug, pydantic cant define with generator
MisanoGo Apr 27, 2023
c33b2bf
update docs
MisanoGo Apr 27, 2023
3519e9a
solve user columns logic bug
MisanoGo Apr 27, 2023
96170c7
update
MisanoGo Apr 27, 2023
e119e23
set get_by_id, docs
MisanoGo Apr 27, 2023
35e1d60
fix bug
MisanoGo Apr 27, 2023
b40717d
write doc
MisanoGo Apr 27, 2023
995fd1f
fix
MisanoGo Apr 27, 2023
4f14861
Write Story
MisanoGo Apr 27, 2023
eece1b5
update
MisanoGo Apr 27, 2023
55c6fb5
update
MisanoGo Apr 27, 2023
9364658
best prectice
MisanoGo Apr 27, 2023
f8bd5e8
add documents
TheMainMamad Apr 27, 2023
77e68c5
add docs argument
TheMainMamad Apr 27, 2023
4e42146
set standard
MisanoGo Apr 27, 2023
9c64a52
fix imports bug
MisanoGo Apr 27, 2023
bfd5cf2
some change
MisanoGo Apr 27, 2023
9823a63
fox bug
MisanoGo Apr 27, 2023
882f07c
solve conflict
MisanoGo Apr 27, 2023
bb721f5
update
MisanoGo Apr 28, 2023
35c7553
implement FoxCon: manage comparison operators
MisanoGo Apr 28, 2023
a0a0359
implement auto backup
MisanoGo Apr 28, 2023
b48fa8f
change level name
MisanoGo Apr 28, 2023
180767e
raname json -> storage
MisanoGo Apr 28, 2023
495201e
set base exception
MisanoGo Apr 29, 2023
25d9804
split
MisanoGo May 1, 2023
e2e5770
change delete method, best practice,...
MisanoGo May 1, 2023
1af4e78
change
MisanoGo May 1, 2023
4f16f3c
change get attribute method
MisanoGo May 1, 2023
0dbae9f
.
MisanoGo May 1, 2023
08cc5ae
update columns
MisanoGo May 1, 2023
72b6883
change delete method & add new data insert method
MisanoGo May 2, 2023
94daef4
best practice
MisanoGo May 2, 2023
a1bad54
update
MisanoGo May 5, 2023
920e2de
update
MisanoGo May 5, 2023
55800e7
full remove FoxNone
MisanoGo May 5, 2023
d787f0f
update test
MisanoGo May 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,5 @@ dmypy.json
# Pyre type checker
.pyre/
.vscode

*.json
140 changes: 109 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,138 @@
# **_FoxLin_**
simple, fast, funny json dbms base on python
simple, fast, funny column based dbms on python

### philosophy
Foxlin is developed to create the best User experience of DBMS interface for mini projects
it is fast because use of numpy array for contain columns data in memory
and using pydantic for manage data in program

also have powerfull process managers.

### feature
* simple & fast
* friendly ux
* auto backup
* nosql structure
* power full query tool based on sql concept
* logging
* async #TODO in 1.1
* smart cache system # TODO in 1.2
* query cache system # TODO in 1.2

### Quick access :
- docs : [todo]()
- [docs](https://GitHub.com/MisanoGo/FoxLin/blob/stable/docs)
- pypi : [todo]()
- code : [todo]()
- [code](https://GitHub.com/MisanoGo/FoxLin)


### Futures :
> - TODO
### requirements
* numpy
* pydantic
* orjson

### Table Structure
TODO

## simple usage :
```Python
from foxlin import FoxLin, Schema
## installation

class MyTable(schema): # define your teble schema
name: str
username: str
password: str
### from pypi
```console
$ pip install foxlin
```

db = FoxLin('./db.json', MyTable)
### from github
``` console
$ git clone https://github.com/MisanoGo/FoxLin && cd FoxLin
$ pytest # run tests
$ pip install -e setup.py
```

## simple usage :
```Python
from foxlin import FoxLin, Schema, column

data = [
MyTable(name='sobhan', username='misano', password='#197382645#'),
MyTable(name='Tommy', username='god_of_war', password='123QWEasdZXC')
]
class MyTable(schema):
# define your teble schema
name: str = column(dtype=str)
age: int = column(dtype=int)
username: str = column(uniqe=True, dtype=str)
password: str = column(dtype=str)

with db.session as db_session:
db_session.INSERT(*data)
db = FoxLin('./db.json', MyTable) # create db

# OR
data = [
MyTable(name='brian', age=37, username='biran1999', password='123456789')
MyTable(name='sobhan', age=20, username='misano', password='#197382645#'),
MyTable(name='Tommy', age=15, username='god_of_war', password='123QWEasdZXC')
MyTable(name='Ali', age=20, username='p_1969_q', password='@QWE123KFH@')
]

db_session = db.sessionFactory
db_session.INSERT(*data)
db_session.COMMIT()
with db.session as db_session:
db_session.insert(*data)
# auto commit in the end of context manager

r_data = db_session.SELECT().WHERE('name','=','sobhan').get()
myrecord = r_data[0]
query = db.query
record = query.where(query.age > 17, query.name == 'Ali').order_by(query.age).first()

print(myrecord.name, myrecord.username, myrecord.password)
print(record.name, record.username, record.password)
```

### Note
- every crud operation on db has O(record_count * column_count) order

## FoxLin Story

Sophy was a curious girl, always looking to learn and explore new things. One day, she found herself surrounded by a dense forest, enchanted by the beauty and mystery it held.

As she walked further into the woods, she stumbled upon a Fox named Lin. Unlike other animals that would normally run away, Lin was as curious as Sophy was. Struck by their shared curiosity, they started talking.

Sophy soon realized that Lin was not just any fox but an intelligent fox with considerable knowledge in the world of data. Excited by this, Sophy began asking Lin questions, eager to learn as much as she could.

As they continued their conversation, they stumbled upon a huge database hidden in the forest that no one else had any idea about. Together, they navigated the vast expanse of knowledge within the database, reading and learning so many new things.

Sophy and Lin lost track of time, as they quenched their thirst for knowledge in this world of data.

As they walked back towards their homes, both of them were overcome with a sense of fulfillment and satisfaction. They realized that the world was full of secrets waiting to be unraveled, and it was up to them to quench their thirst for knowledge and explore all the possibilities.

From that day on, Sophy and Lin would often visit the database and other places together, learning new things and exploring the world of data. They knew that knowledge had no limit and that there was always something new to discover, and it was this knowledge that would bring them closer every day.
(generated by ai).


**my experience from this project**
* in operations with high order, when have many static if,else(no change in all of program)
it's better to split their by classes and use factory clasess for select own usefull class, etc : columns.py:column


## TODO

##### TODO in 1.0
- [x] crud
- [x] level base operation manager
- [x] self log system
- [x] session model
- [x] transaction but by grouping commits **not ACDI**
- [ ] write test
- [ ] neo dict implemented by numpy
- [ ] add logs to .<database-name>.logs
- [ ] genetate logs
- [ ] quering
- [x] write test
- [x] benchmarck test
- [x] add logs to .logs file
- [x] define logs in operation statment and able to setting by user
- [x] generate logs
- [x] quering
- [x] auto backup

##### TODO at 1.1
- asynchronus
- transaction ACDI
- define Group By & HAVING
- log time duration of operation's
- migrate
- stub
- data compretion

##### TODO at 1.2
- memory cache system
- query cache system
- session privilege's
- multi table
- ...


Empty file added config/__init__.py
Empty file.
9 changes: 9 additions & 0 deletions config/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# FoxLin Configuration file

import os

from pathlib import Path

BASE_DIR = os.path.realpath(Path(__file__).parent.parent)

AUTO_RUNNING_TESTS = False
20 changes: 20 additions & 0 deletions documents/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
35 changes: 35 additions & 0 deletions documents/make.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@ECHO OFF

pushd %~dp0

REM Command file for Sphinx documentation

if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build

%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.https://www.sphinx-doc.org/
exit /b 1
)

if "%1" == "" goto help

%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end

:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%

:end
popd
19 changes: 19 additions & 0 deletions documents/source/HOW_TO.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
:orphan:


TODO : write discription
========================

how to : disable log
.. code-block:: Python

db = FoxLin(...)
db.disable_box('log')


how to : use just in memory
===========================
.. code-block:: Python

db = FoxLin(..., auto_setup=False)
db.disable_box('jsonfile') # return True if success
1 change: 1 addition & 0 deletions documents/source/HOW_WORK.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
:orphan:
111 changes: 111 additions & 0 deletions documents/source/QUICK_START.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
:orphan:

QUICK START
===========

define table schema
===================

.. code-block:: Python

from foxlin import Schema, Column, UniqeColumn

class MyTable(Schema):
name : str = Column()
age : int = Column()
username: str = UniqeColumn()


initial db instance
===================

.. code-block:: Python

from foxlin import FoxLin

db_path = './db.json' # set path of database

db = FoxLin(db_path, MyTable)



CRUD
====
.. code-block:: Python

# insert
data = MyTable(
name = 'tom',
age = 17,
username = 'tomtom'
)

# insert data
with db.session as session:
session.insert(data)



data.age = 18
session.update(data, updated_field=['age'])


# delete data
session.delete(data.ID)


Query
=====
.. code-block:: Python

# get query
query = session.query
# OR
query = db.query


# select columns
query.select('age','name')


# get first record
record = query.first()


# get end
record = query.end()


# get random record
record = query.rand()


# get all
records = query.select('age','username').all() # return generator
record_list = list(records)


# access column data
name_data = query.name
age_data = query.age


# filter records
filterd_rec = query.select('username').where(q.age > 50, q.name == 'some name').first()


# sort records
sorted_recs = query.where(query.age == 17).select('age').order_by(query.age).first()


# max, min, mean
query.where(query.age == 17)
query.order_by(query.age)

max_rec = query.max()
min_rec = query.min()
mean_rec = query.mean()


# limit records
10_rec = query.limit(10).all()
Loading