Skip to content

Commit e633fde

Browse files
committed
Merge branch 'fix/nested-relations' of https://github.com/MasoniteFramework/orm into fix/nested-relations
2 parents 3fec41b + 27cee27 commit e633fde

File tree

124 files changed

+2154
-1414
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+2154
-1414
lines changed

cc.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,16 +53,14 @@ def articles(self):
5353

5454

5555
class Company(Model):
56-
__connection__ = "sqlite"
57-
58-
56+
__connection__ = "t"
5957
# /Users/personal/programming/masonite/packages/orm/src/masoniteorm/query/QueryBuilder.py
6058

6159
# user = User.create({"name": "phill", "email": "phill"})
6260
# print(inspect.isclass(User))
6361
user = User.with_("articles.logos.user").first()
6462
# user.update({"verified_at": None, "updated_at": None})
65-
# print(user.articles)
63+
print(user.articles)
6664

6765
print(user.serialize())
6866
# print(User.first())

src/masoniteorm/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
from .models import Model
21
from .factories.Factory import Factory
2+
from .models import Model

src/masoniteorm/collection/Collection.py

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import json
2-
import random
32
import operator
3+
import random
44
from functools import reduce
55

66

@@ -310,7 +310,9 @@ def random(self, count=None):
310310
if collection_count == 0:
311311
return None
312312
elif count and count > collection_count:
313-
raise ValueError("count argument must be inferior to collection length.")
313+
raise ValueError(
314+
"count argument must be inferior to collection length."
315+
)
314316
elif count:
315317
self._items = random.sample(self._items, k=count)
316318
return self
@@ -330,15 +332,38 @@ def reverse(self):
330332
self._items = self[::-1]
331333

332334
def serialize(self, *args, **kwargs):
335+
"""Serialize the collection into a list of dictionaries.
336+
337+
Returns:
338+
list: Returns a list of dictionaries.
339+
"""
340+
333341
def _serialize(item):
334-
if self.__appends__:
335-
item.set_appends(self.__appends__)
342+
if not hasattr(item, "serialize"):
343+
return item
344+
345+
# Check if this item has already been serialized
346+
if not hasattr(self, "_serialized_objects"):
347+
self._serialized_objects = set()
348+
349+
if id(item) in self._serialized_objects:
350+
# Return just the primary key if it's a circular reference
351+
return (
352+
item.get_primary_key_value()
353+
if hasattr(item, "get_primary_key_value")
354+
else None
355+
)
356+
357+
# Add this item to the set of serialized objects
358+
self._serialized_objects.add(id(item))
359+
360+
# Serialize the item
361+
result = item.serialize(*args, **kwargs)
362+
363+
# Remove this item from the set of serialized objects
364+
self._serialized_objects.remove(id(item))
336365

337-
if hasattr(item, "serialize"):
338-
return item.serialize(*args, **kwargs)
339-
elif hasattr(item, "to_dict"):
340-
return item.to_dict()
341-
return item
366+
return result
342367

343368
return list(map(_serialize, self))
344369

@@ -424,17 +449,17 @@ def where(self, key, *args):
424449
if isinstance(item, dict):
425450
comparison = item.get(key)
426451
else:
427-
comparison = getattr(item, key) if hasattr(item, key) else False
452+
comparison = (
453+
getattr(item, key) if hasattr(item, key) else False
454+
)
428455
if self._make_comparison(comparison, value, op):
429456
attributes.append(item)
430457
return self.__class__(attributes)
431458

432459
def where_in(self, key, args: list) -> "Collection":
433460
# Compatibility patch - allow numeric strings to match integers
434461
# (if all args are numeric strings)
435-
if all(
436-
[isinstance(arg, str) and arg.isnumeric() for arg in args]
437-
):
462+
if all([isinstance(arg, str) and arg.isnumeric() for arg in args]):
438463
return self.where_in(key, [int(arg) for arg in args])
439464

440465
attributes = []
@@ -457,9 +482,7 @@ def where_in(self, key, args: list) -> "Collection":
457482
def where_not_in(self, key, args: list) -> "Collection":
458483
# Compatibility patch - allow numeric strings to match integers
459484
# (if all args are numeric strings)
460-
if all(
461-
[isinstance(arg, str) and arg.isnumeric() for arg in args]
462-
):
485+
if all([isinstance(arg, str) and arg.isnumeric() for arg in args]):
463486
return self.where_not_in(key, [int(arg) for arg in args])
464487

465488
attributes = []
@@ -482,7 +505,9 @@ def where_not_in(self, key, args: list) -> "Collection":
482505
def zip(self, items):
483506
items = self.__get_items(items)
484507
if not isinstance(items, list):
485-
raise ValueError("The 'items' parameter must be a list or a Collection")
508+
raise ValueError(
509+
"The 'items' parameter must be a list or a Collection"
510+
)
486511

487512
_items = []
488513
for x, y in zip(self, items):

src/masoniteorm/commands/Entry.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@
66
"""
77

88
from cleo import Application
9+
910
from . import (
10-
MigrateCommand,
11-
MigrateRollbackCommand,
12-
MigrateRefreshCommand,
13-
MigrateFreshCommand,
1411
MakeMigrationCommand,
1512
MakeModelCommand,
1613
MakeModelDocstringCommand,
1714
MakeObserverCommand,
18-
MigrateStatusCommand,
19-
MigrateResetCommand,
2015
MakeSeedCommand,
16+
MigrateCommand,
17+
MigrateFreshCommand,
18+
MigrateRefreshCommand,
19+
MigrateResetCommand,
20+
MigrateRollbackCommand,
21+
MigrateStatusCommand,
2122
SeedRunCommand,
2223
ShellCommand,
2324
)

src/masoniteorm/commands/MakeMigrationCommand.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ def handle(self):
3737

3838
with open(
3939
os.path.join(
40-
pathlib.Path(__file__).parent.absolute(), f"stubs/{stub_file}.stub"
40+
pathlib.Path(__file__).parent.absolute(),
41+
f"stubs/{stub_file}.stub",
4142
)
4243
) as fp:
4344
output = fp.read()
@@ -46,7 +47,9 @@ def handle(self):
4647

4748
file_name = f"{now.strftime('%Y_%m_%d_%H%M%S')}_{name}.py"
4849

49-
with open(os.path.join(os.getcwd(), migration_directory, file_name), "w") as fp:
50+
with open(
51+
os.path.join(os.getcwd(), migration_directory, file_name), "w"
52+
) as fp:
5053
fp.write(output)
5154

5255
self.info(

src/masoniteorm/commands/MakeModelCommand.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ def handle(self):
2828
model_directory = self.option("directory")
2929

3030
with open(
31-
os.path.join(pathlib.Path(__file__).parent.absolute(), "stubs/model.stub")
31+
os.path.join(
32+
pathlib.Path(__file__).parent.absolute(), "stubs/model.stub"
33+
)
3234
) as fp:
3335
output = fp.read()
3436
output = output.replace("__CLASS__", camelize(name))
@@ -46,9 +48,13 @@ def handle(self):
4648
)
4749
return
4850

49-
os.makedirs(os.path.dirname(os.path.join(full_directory_path)), exist_ok=True)
51+
os.makedirs(
52+
os.path.dirname(os.path.join(full_directory_path)), exist_ok=True
53+
)
5054

51-
with open(os.path.join(os.getcwd(), model_directory, file_name), "w+") as fp:
55+
with open(
56+
os.path.join(os.getcwd(), model_directory, file_name), "w+"
57+
) as fp:
5258
fp.write(output)
5359

5460
self.info(f"Model created: {os.path.join(model_directory, file_name)}")
@@ -67,4 +73,6 @@ def handle(self):
6773

6874
if self.option("seeder"):
6975
directory = self.option("seeders-directory")
70-
self.call("seed", f"{self.argument('name')} --directory {directory}")
76+
self.call(
77+
"seed", f"{self.argument('name')} --directory {directory}"
78+
)

src/masoniteorm/commands/MakeObserverCommand.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ def handle(self):
4646

4747
os.makedirs(os.path.join(full_directory_path), exist_ok=True)
4848

49-
with open(os.path.join(os.getcwd(), observer_directory, file_name), "w+") as fp:
49+
with open(
50+
os.path.join(os.getcwd(), observer_directory, file_name), "w+"
51+
) as fp:
5052
fp.write(output)
5153

5254
self.info(f"Observer created: {file_name}")

src/masoniteorm/commands/MakeSeedCommand.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,26 @@ def handle(self):
2727

2828
with open(
2929
os.path.join(
30-
pathlib.Path(__file__).parent.absolute(), f"stubs/{stub_file}.stub"
30+
pathlib.Path(__file__).parent.absolute(),
31+
f"stubs/{stub_file}.stub",
3132
)
3233
) as fp:
3334
output = fp.read()
3435
output = output.replace("__SEEDER_NAME__", camelize(name))
3536

3637
file_name = f"{underscore(name)}.py"
37-
full_path = pathlib.Path(os.path.join(os.getcwd(), seed_directory, file_name))
38+
full_path = pathlib.Path(
39+
os.path.join(os.getcwd(), seed_directory, file_name)
40+
)
3841

39-
path_normalized = pathlib.Path(seed_directory) / pathlib.Path(file_name)
42+
path_normalized = pathlib.Path(seed_directory) / pathlib.Path(
43+
file_name
44+
)
4045

4146
if os.path.exists(full_path):
42-
return self.line(f"<error>{path_normalized} already exists.</error>")
47+
return self.line(
48+
f"<error>{path_normalized} already exists.</error>"
49+
)
4350

4451
with open(full_path, "w") as fp:
4552
fp.write(output)

src/masoniteorm/commands/MigrateFreshCommand.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from ..migrations import Migration
2-
32
from .Command import Command
43

54

src/masoniteorm/commands/MigrateRefreshCommand.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from ..migrations import Migration
2-
32
from .Command import Command
43

54

src/masoniteorm/commands/MigrateRollbackCommand.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,6 @@ def handle(self):
2121
migration_directory=self.option("directory"),
2222
config_path=self.option("config"),
2323
schema=self.option("schema"),
24-
).rollback(migration=self.option("migration"), output=self.option("show"))
24+
).rollback(
25+
migration=self.option("migration"), output=self.option("show")
26+
)

src/masoniteorm/commands/SeedRunCommand.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ def handle(self):
2828

2929
else:
3030
table = self.argument("table")
31-
seeder_file = (
32-
f"{underscore(table)}_table_seeder.{camelize(table)}TableSeeder"
33-
)
31+
seeder_file = f"{underscore(table)}_table_seeder.{camelize(table)}TableSeeder"
3432
seeder.run_specific_seed(seeder_file)
3533
seeder_seeded = f"{camelize(table)}TableSeeder"
3634

src/masoniteorm/commands/ShellCommand.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
import subprocess
21
import os
32
import re
43
import shlex
4+
import subprocess
55
from collections import OrderedDict
66

77
from ..config import load_config
8-
98
from .Command import Command
109

1110

@@ -107,7 +106,9 @@ def get_mysql_args(self, config):
107106
"--port": config.get("port"),
108107
"--user": config.get("user"),
109108
"--password": config.get("password"),
110-
"--default-character-set": config.get("options", {}).get("charset"),
109+
"--default-character-set": config.get("options", {}).get(
110+
"charset"
111+
),
111112
}
112113
)
113114
return args, options
@@ -136,7 +137,9 @@ def get_mssql_args(self, config):
136137
if config.get("port"):
137138
server += f",{config.get('port')}"
138139

139-
trusted_connection = config.get("options").get("trusted_connection") == "Yes"
140+
trusted_connection = (
141+
config.get("options").get("trusted_connection") == "Yes"
142+
)
140143
options = OrderedDict(
141144
{
142145
"-d": config.get("database"),
@@ -172,7 +175,9 @@ def remove_empty_options(self, options):
172175
def get_sensitive_options(self, config):
173176
driver = config.get("full_details").get("driver")
174177
try:
175-
sensitive_options = getattr(self, f"get_{driver}_sensitive_options")()
178+
sensitive_options = getattr(
179+
self, f"get_{driver}_sensitive_options"
180+
)()
176181
except AttributeError:
177182
sensitive_options = []
178183
return sensitive_options
@@ -194,5 +199,7 @@ def hide_sensitive_options(self, config, command):
194199
if option in command:
195200
match = re.search(rf"{option} (\w+)", command)
196201
if match.groups():
197-
cleaned_command = cleaned_command.replace(match.groups()[0], "***")
202+
cleaned_command = cleaned_command.replace(
203+
match.groups()[0], "***"
204+
)
198205
return cleaned_command

src/masoniteorm/commands/__init__.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33

44
sys.path.append(os.getcwd())
55

6-
from .MigrateCommand import MigrateCommand
7-
from .MigrateRollbackCommand import MigrateRollbackCommand
8-
from .MigrateRefreshCommand import MigrateRefreshCommand
9-
from .MigrateFreshCommand import MigrateFreshCommand
10-
from .MigrateResetCommand import MigrateResetCommand
6+
from .MakeMigrationCommand import MakeMigrationCommand
117
from .MakeModelCommand import MakeModelCommand
128
from .MakeModelDocstringCommand import MakeModelDocstringCommand
139
from .MakeObserverCommand import MakeObserverCommand
14-
from .MigrateStatusCommand import MigrateStatusCommand
15-
from .MakeMigrationCommand import MakeMigrationCommand
1610
from .MakeSeedCommand import MakeSeedCommand
11+
from .MigrateCommand import MigrateCommand
12+
from .MigrateFreshCommand import MigrateFreshCommand
13+
from .MigrateRefreshCommand import MigrateRefreshCommand
14+
from .MigrateResetCommand import MigrateResetCommand
15+
from .MigrateRollbackCommand import MigrateRollbackCommand
16+
from .MigrateStatusCommand import MigrateStatusCommand
1717
from .SeedRunCommand import SeedRunCommand
1818
from .ShellCommand import ShellCommand

src/masoniteorm/config.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
import pydoc
33
import urllib.parse as urlparse
44

5-
from .exceptions import ConfigurationNotFound
6-
from .exceptions import InvalidUrlConfiguration
5+
from .exceptions import ConfigurationNotFound, InvalidUrlConfiguration
76

87

98
def load_config(config_path=None):
@@ -98,7 +97,9 @@ def db_url(database_url=None, prefix="", options={}, log_queries=False):
9897
# lookup specified driver
9998
driver = DRIVERS_MAP[url.scheme]
10099
port = (
101-
str(url.port) if url.port and driver in [DRIVERS_MAP["mssql"]] else url.port
100+
str(url.port)
101+
if url.port and driver in [DRIVERS_MAP["mssql"]]
102+
else url.port
102103
)
103104

104105
# build final configuration

0 commit comments

Comments
 (0)