Skip to content

Commit

Permalink
Merge pull request #769 from MasoniteFramework/feature/759
Browse files Browse the repository at this point in the history
Feature/759
  • Loading branch information
josephmancuso authored Jul 20, 2022
2 parents abac944 + acfeb3b commit 1f788da
Show file tree
Hide file tree
Showing 24 changed files with 347 additions and 107 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# Versions should comply with PEP440. For a discussion on single-sourcing
# the version across setup.py and the project code, see
# https://packaging.python.org/en/latest/single_source_version.html
version="2.17.0",
version="2.18.1",
package_dir={"": "src"},
description="The Official Masonite ORM",
long_description=long_description,
Expand Down
2 changes: 1 addition & 1 deletion src/masoniteorm/commands/MigrateRefreshCommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def handle(self):
connection=self.option("connection"),
migration_directory=self.option("directory"),
config_path=self.option("config"),
schema=self.option("schema")
schema=self.option("schema"),
)

migration.refresh(self.option("migration"))
Expand Down
3 changes: 2 additions & 1 deletion src/masoniteorm/commands/stubs/table_migration.stub
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ class __MIGRATION_NAME__(Migration):
"""
Revert the migrations.
"""
pass
with self.schema.table("__TABLE_NAME__") as table:
pass
4 changes: 3 additions & 1 deletion src/masoniteorm/connections/ConnectionResolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ def get_schema_builder(self, connection="default", schema=None):
from ..schema import Schema

return Schema(
connection=connection, connection_details=self.get_connection_details(), schema=schema
connection=connection,
connection_details=self.get_connection_details(),
schema=schema,
)

def get_query_builder(self, connection="default"):
Expand Down
21 changes: 14 additions & 7 deletions src/masoniteorm/migrations/Migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ def __init__(
DATABASES = DB.get_connection_details()

self.schema = Schema(
connection=connection, connection_details=DATABASES, dry=dry, schema=self.schema_name
connection=connection,
connection_details=DATABASES,
dry=dry,
schema=self.schema_name,
)

self.migration_model = MigrationModel.on(self.connection)
Expand Down Expand Up @@ -137,7 +140,9 @@ def migrate(self, migration="all", output=False):
f"<comment>Migrating:</comment> <question>{migration}</question>"
)

migration_class = migration_class(connection=self.connection, schema=self.schema_name)
migration_class = migration_class(
connection=self.connection, schema=self.schema_name
)

if output:
migration_class.schema.dry()
Expand Down Expand Up @@ -187,7 +192,9 @@ def rollback(self, migration="all", output=False):
self.command_class.line(f"<error>Not Found: {migration}</error>")
continue

migration_class = migration_class(connection=self.connection, schema=self.schema_name)
migration_class = migration_class(
connection=self.connection, schema=self.schema_name
)

if output:
migration_class.schema.dry()
Expand Down Expand Up @@ -237,9 +244,7 @@ def reset(self, migration="all"):

if not len(migrations):
if self.command_class:
self.command_class.line(
"<info>Nothing to reset</info>"
)
self.command_class.line("<info>Nothing to reset</info>")
else:
print("Nothing to reset")

Expand All @@ -250,7 +255,9 @@ def reset(self, migration="all"):
)

try:
self.locate(migration)(connection=self.connection, schema=self.schema_name).down()
self.locate(migration)(
connection=self.connection, schema=self.schema_name
).down()
except TypeError:
self.command_class.line(f"<error>Not Found: {migration}</error>")
continue
Expand Down
61 changes: 49 additions & 12 deletions src/masoniteorm/models/Model.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import logging
from decimal import Decimal

from inflection import tableize
from inflection import tableize, underscore
import inspect

import pendulum
Expand Down Expand Up @@ -58,12 +58,17 @@ class JsonCast:
"""Casts a value to JSON"""

def get(self, value):
if isinstance(value, dict) or isinstance(value, list):
return value
if not isinstance(value, str):
return json.dumps(value)

return json.loads(value)
return value

def set(self, value):
if isinstance(value, str):
# make sure the string is valid JSON
json.loads(value)
return value

return json.dumps(value)


Expand Down Expand Up @@ -138,6 +143,7 @@ class Model(TimeStampsMixin, ObservesEvents, metaclass=ModelMeta):
_booted = False
_scopes = {}
__primary_key__ = "id"
__primary_key_type__ = "int"
__casts__ = {}
__dates__ = []
__hidden__ = []
Expand Down Expand Up @@ -282,6 +288,14 @@ def get_primary_key(self):
"""
return self.__primary_key__

def get_primary_key_type(self):
"""Gets the primary key column type
Returns:
mixed
"""
return self.__primary_key_type__

def get_primary_key_value(self):
"""Gets the primary key value.
Expand All @@ -300,6 +314,17 @@ def get_primary_key_value(self):
f"class '{name}' has no attribute {self.get_primary_key()}. Did you set the primary key correctly on the model using the __primary_key__ attribute?"
)

def get_foreign_key(self):
"""Gets the foreign key based on this model name.
Args:
relationship (str): The relationship name.
Returns:
str
"""
return underscore(self.__class__.__name__ + "_" + self.get_primary_key())

def query(self):
return self.get_builder()

Expand Down Expand Up @@ -723,13 +748,6 @@ def __getattr__(self, attribute):
mixed: Could be anything that a method can return.
"""

if attribute in self.__passthrough__:

def method(*args, **kwargs):
return getattr(self.get_builder(), attribute)(*args, **kwargs)

return method

new_name_accessor = "get_" + attribute + "_attribute"

if (new_name_accessor) in self.__class__.__dict__:
Expand All @@ -753,6 +771,13 @@ def method(*args, **kwargs):
)
return self.get_value(attribute)

if attribute in self.__passthrough__:

def method(*args, **kwargs):
return getattr(self.get_builder(), attribute)(*args, **kwargs)

return method

if attribute in self.__dict__.get("_relationships", {}):
return self.__dict__["_relationships"][attribute]

Expand Down Expand Up @@ -896,6 +921,18 @@ def _set_cast_attribute(self, attribute, value):

return cast_method(value)

def transform_dict(self, attributes: dict):
new_dict = {}
for key, value in attributes.items():
if key in self.get_dates():
new_dict.update({key: self.get_new_datetime_string(value)})
elif key in self.__casts__:
new_dict.update({key: self._cast_attribute(key, value)})
else:
new_dict.update({key: value})

return new_dict

@classmethod
def load(cls, *loads):
cls.boot()
Expand Down Expand Up @@ -996,7 +1033,7 @@ def detach_many(self, relation, relating_records):
else:
related_record.save()

related.detach_related(self, related_record)
related.detach(self, related_record)

def related(self, relation):
related = getattr(self.__class__, relation)
Expand Down
8 changes: 7 additions & 1 deletion src/masoniteorm/query/EagerRelation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ class EagerRelations:
def __init__(self, relation=None):
self.eagers = []
self.nested_eagers = {}
self.callback_eagers = {}
self.is_nested = False
self.relation = relation

def register(self, *relations):
def register(self, *relations, callback=None):
for relation in relations:
if isinstance(relation, str) and "." not in relation:
self.eagers += [relation]
Expand All @@ -20,6 +21,8 @@ def register(self, *relations):
for eagers in relations:
for eager in eagers:
self.register(eager)
elif isinstance(relation, dict):
self.callback_eagers.update(relation)

return self

Expand All @@ -31,4 +34,7 @@ def get_eagers(self):
if self.nested_eagers:
eagers.append(self.nested_eagers)

if self.callback_eagers:
eagers.append(self.callback_eagers)

return eagers
Loading

0 comments on commit 1f788da

Please sign in to comment.