Skip to content

Commit

Permalink
Merge pull request #771 from MasoniteFramework/feature/748-1
Browse files Browse the repository at this point in the history
Add more methods to schema builder
  • Loading branch information
josephmancuso authored Dec 6, 2023
2 parents 74355a3 + 9bed4f8 commit 45b6323
Show file tree
Hide file tree
Showing 13 changed files with 191 additions and 27 deletions.
54 changes: 47 additions & 7 deletions src/masoniteorm/schema/Blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ def decimal(self, column, length=17, precision=6, nullable=False):
Returns:
self
"""

self._last_column = self.table.add_column(
column,
"decimal",
Expand Down Expand Up @@ -483,6 +484,46 @@ def text(self, column, length=None, nullable=False):
)
return self

def tiny_text(self, column, length=None, nullable=False):
"""Sets a column to be the text representation for the table.
Arguments:
column {string} -- The column name.
Keyword Arguments:
length {int} -- The length of the column if any. (default: {False})
nullable {bool} -- Whether the column is nullable. (default: {False})
Returns:
self
"""
self._last_column = self.table.add_column(
column, "tiny_text", length=length, nullable=nullable
)
return self

def unsigned_decimal(self, column, length=17, precision=6, nullable=False):
"""Sets a column to be the text representation for the table.
Arguments:
column {string} -- The column name.
Keyword Arguments:
length {int} -- The length of the column if any. (default: {False})
nullable {bool} -- Whether the column is nullable. (default: {False})
Returns:
self
"""
self._last_column = self.table.add_column(
column,
"decimal",
length="{length}, {precision}".format(length=length, precision=precision),
nullable=nullable,
).unsigned()
return self
return self

def long_text(self, column, length=None, nullable=False):
"""Sets a column to be the long_text representation for the table.
Expand Down Expand Up @@ -643,13 +684,12 @@ def unsigned(self, column=None, length=None, nullable=False):
self
"""
if not column:
self._last_column.column_type += "_unsigned"
self._last_column.length = None
self._last_column.unsigned()
return self

self._last_column = self.table.add_column(
column, "unsigned", length=length, nullable=nullable
)
).unsigned()
return self

def unsigned_integer(self, column, nullable=False):
Expand All @@ -665,8 +705,8 @@ def unsigned_integer(self, column, nullable=False):
self
"""
self._last_column = self.table.add_column(
column, "integer_unsigned", nullable=nullable
)
column, "integer", nullable=nullable
).unsigned()
return self

def morphs(self, column, nullable=False, indexes=True):
Expand All @@ -684,8 +724,8 @@ def morphs(self, column, nullable=False, indexes=True):
_columns = []
_columns.append(
self.table.add_column(
"{}_id".format(column), "integer_unsigned", nullable=nullable
)
"{}_id".format(column), "integer", nullable=nullable
).unsigned()
)
_columns.append(
self.table.add_column(
Expand Down
20 changes: 20 additions & 0 deletions src/masoniteorm/schema/Column.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ def __init__(
values=None,
nullable=False,
default=None,
signed=None,
default_is_raw=False,
column_python_type=str,
):
Expand All @@ -21,6 +22,7 @@ def __init__(
self._after = None
self.old_column = ""
self.default = default
self._signed = signed
self.default_is_raw = default_is_raw
self.primary = False
self.comment = None
Expand All @@ -34,6 +36,24 @@ def nullable(self):
self.is_null = True
return self

def signed(self):
"""Sets this column to be nullable
Returns:
self
"""
self._signed = "signed"
return self

def unsigned(self):
"""Sets this column to be nullable
Returns:
self
"""
self._signed = "unsigned"
return self

def not_nullable(self):
"""Sets this column to be not nullable
Expand Down
2 changes: 2 additions & 0 deletions src/masoniteorm/schema/Table.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def add_column(
values=None,
nullable=False,
default=None,
signed=None,
default_is_raw=False,
primary=False,
column_python_type=str,
Expand All @@ -36,6 +37,7 @@ def add_column(
nullable=nullable,
values=values or [],
default=default,
signed=signed,
default_is_raw=default_is_raw,
column_python_type=column_python_type,
)
Expand Down
1 change: 1 addition & 0 deletions src/masoniteorm/schema/platforms/MSSQLPlatform.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class MSSQLPlatform(Platform):
"double": "DOUBLE",
"enum": "VARCHAR",
"text": "TEXT",
"tiny_text": "TINYTEXT",
"float": "FLOAT",
"geometry": "GEOMETRY",
"json": "JSON",
Expand Down
16 changes: 13 additions & 3 deletions src/masoniteorm/schema/platforms/MySQLPlatform.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class MySQLPlatform(Platform):
"double": "DOUBLE",
"enum": "ENUM",
"text": "TEXT",
"tiny_text": "TINYTEXT",
"float": "FLOAT",
"geometry": "GEOMETRY",
"json": "JSON",
Expand All @@ -55,6 +56,8 @@ class MySQLPlatform(Platform):
"null": " DEFAULT NULL",
}

signed = {"unsigned": "UNSIGNED", "signed": "SIGNED"}

def columnize(self, columns):
sql = []
for name, column in columns.items():
Expand Down Expand Up @@ -87,7 +90,6 @@ def columnize(self, columns):
if column.column_type == "enum":
values = ", ".join(f"'{x}'" for x in column.values)
column_constraint = f"({values})"

sql.append(
self.columnize_string()
.format(
Expand All @@ -98,6 +100,9 @@ def columnize(self, columns):
constraint=constraint,
nullable=self.premapped_nulls.get(column.is_null) or "",
default=default,
signed=" " + self.signed.get(column._signed)
if column._signed
else "",
comment="COMMENT '" + column.comment + "'"
if column.comment
else "",
Expand Down Expand Up @@ -180,6 +185,9 @@ def compile_alter_sql(self, table):
constraint="PRIMARY KEY" if column.primary else "",
nullable="NULL" if column.is_null else "NOT NULL",
default=default,
signed=" " + self.signed.get(column._signed)
if column._signed
else "",
after=(" AFTER " + self.wrap_column(column._after))
if column._after
else "",
Expand Down Expand Up @@ -324,7 +332,9 @@ def compile_alter_sql(self, table):
return sql

def add_column_string(self):
return "ADD {name} {data_type}{length} {nullable}{default}{after}{comment}"
return (
"ADD {name} {data_type}{length}{signed} {nullable}{default}{after}{comment}"
)

def drop_column_string(self):
return "DROP COLUMN {name}"
Expand All @@ -336,7 +346,7 @@ def rename_column_string(self):
return "CHANGE {old} {to}"

def columnize_string(self):
return "{name} {data_type}{length}{column_constraint} {nullable}{default} {constraint}{comment}"
return "{name} {data_type}{length}{column_constraint}{signed} {nullable}{default} {constraint}{comment}"

def constraintize(self, constraints, table):
sql = []
Expand Down
2 changes: 2 additions & 0 deletions src/masoniteorm/schema/platforms/Platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class Platform:
"default": "SET DEFAULT",
}

signed = {"signed": "SIGNED", "unsigned": "UNSIGNED"}

def columnize(self, columns):
sql = []
for name, column in columns.items():
Expand Down
1 change: 1 addition & 0 deletions src/masoniteorm/schema/platforms/PostgresPlatform.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class PostgresPlatform(Platform):
"double": "DOUBLE PRECISION",
"enum": "VARCHAR",
"text": "TEXT",
"tiny_text": "TEXT",
"float": "FLOAT",
"geometry": "GEOMETRY",
"json": "JSON",
Expand Down
15 changes: 13 additions & 2 deletions src/masoniteorm/schema/platforms/SQLitePlatform.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class SQLitePlatform(Platform):
"medium_integer",
]

types_without_signs = ["decimal"]

type_map = {
"string": "VARCHAR",
"char": "CHAR",
Expand All @@ -34,6 +36,7 @@ class SQLitePlatform(Platform):
"double": "DOUBLE",
"enum": "VARCHAR",
"text": "TEXT",
"tiny_text": "TEXT",
"float": "FLOAT",
"geometry": "GEOMETRY",
"json": "JSON",
Expand Down Expand Up @@ -132,6 +135,10 @@ def columnize(self, columns):
data_type=self.type_map.get(column.column_type, ""),
column_constraint=column_constraint,
length=length,
signed=" " + self.signed.get(column._signed)
if column.column_type not in self.types_without_signs
and column._signed
else "",
constraint=constraint,
nullable=self.premapped_nulls.get(column.is_null) or "",
default=default,
Expand Down Expand Up @@ -169,12 +176,16 @@ def compile_alter_sql(self, diff):
constraint = f" REFERENCES {self.wrap_table(foreign_key.foreign_table)}({self.wrap_column(foreign_key.foreign_column)})"

sql.append(
"ALTER TABLE {table} ADD COLUMN {name} {data_type} {nullable}{default}{constraint}".format(
"ALTER TABLE {table} ADD COLUMN {name} {data_type}{signed} {nullable}{default}{constraint}".format(
table=self.wrap_table(diff.name),
name=self.wrap_column(column.name),
data_type=self.type_map.get(column.column_type, ""),
nullable="NULL" if column.is_null else "NOT NULL",
default=default,
signed=" " + self.signed.get(column._signed)
if column.column_type not in self.types_without_signs
and column._signed
else "",
constraint=constraint,
).strip()
)
Expand Down Expand Up @@ -286,7 +297,7 @@ def create_column_length(self, column_type):
return "({length})"

def columnize_string(self):
return "{name} {data_type}{length}{column_constraint} {nullable}{default} {constraint}"
return "{name} {data_type}{length}{column_constraint}{signed} {nullable}{default} {constraint}"

def get_unique_constraint_string(self):
return "UNIQUE({columns})"
Expand Down
20 changes: 20 additions & 0 deletions tests/mssql/schema/test_mssql_schema_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,26 @@ def test_can_add_columns(self):
["CREATE TABLE [users] ([name] VARCHAR(255) NOT NULL, [age] INT NOT NULL)"],
)

def test_can_add_tiny_text(self):
with self.schema.create("users") as blueprint:
blueprint.tiny_text("description")

self.assertEqual(len(blueprint.table.added_columns), 1)
self.assertEqual(
blueprint.to_sql(),
["CREATE TABLE [users] ([description] TINYTEXT NOT NULL)"],
)

def test_can_add_unsigned_decimal(self):
with self.schema.create("users") as blueprint:
blueprint.unsigned_decimal("amount", 19, 4)

self.assertEqual(len(blueprint.table.added_columns), 1)
self.assertEqual(
blueprint.to_sql(),
["CREATE TABLE [users] ([amount] DECIMAL(19, 4) NOT NULL)"],
)

def test_can_add_columns_with_constaint(self):
with self.schema.create("users") as blueprint:
blueprint.string("name")
Expand Down
37 changes: 29 additions & 8 deletions tests/mysql/schema/test_mysql_schema_builder.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import os
import unittest

from src.masoniteorm.models import Model
from src.masoniteorm import Model
from tests.integrations.config.database import DATABASES
from src.masoniteorm.connections import MySQLConnection
from src.masoniteorm.schema import Schema
from src.masoniteorm.schema.platforms import MySQLPlatform
Expand Down Expand Up @@ -38,6 +39,26 @@ def test_can_add_columns1(self):
],
)

def test_can_add_tiny_text(self):
with self.schema.create("users") as blueprint:
blueprint.tiny_text("description")

self.assertEqual(len(blueprint.table.added_columns), 1)
self.assertEqual(
blueprint.to_sql(),
["CREATE TABLE `users` (`description` TINYTEXT NOT NULL)"],
)

def test_can_add_unsigned_decimal(self):
with self.schema.create("users") as blueprint:
blueprint.unsigned_decimal("amount", 19, 4)

self.assertEqual(len(blueprint.table.added_columns), 1)
self.assertEqual(
blueprint.to_sql(),
["CREATE TABLE `users` (`amount` DECIMAL(19, 4) UNSIGNED NOT NULL)"],
)

def test_can_create_table_if_not_exists(self):
with self.schema.create_table_if_not_exists("users") as blueprint:
blueprint.string("name")
Expand Down Expand Up @@ -204,7 +225,7 @@ def test_can_advanced_table_creation2(self):
"CREATE TABLE `users` (`id` BIGINT UNSIGNED AUTO_INCREMENT NOT NULL, `name` VARCHAR(255) NOT NULL, "
"`duration` VARCHAR(255) NOT NULL, `url` VARCHAR(255) NOT NULL, `last_address` VARCHAR(255) NULL, `route_origin` VARCHAR(255) NULL, `mac_address` VARCHAR(255) NULL, "
"`published_at` DATETIME NOT NULL, `thumbnail` VARCHAR(255) NULL, "
"`premium` INT(11) NOT NULL, `author_id` INT UNSIGNED NULL, `description` TEXT NOT NULL, `created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP, "
"`premium` INT(11) NOT NULL, `author_id` INT(11) UNSIGNED NULL, `description` TEXT NOT NULL, `created_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP, "
"`updated_at` DATETIME NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT users_id_primary PRIMARY KEY (id), CONSTRAINT users_author_id_foreign FOREIGN KEY (`author_id`) REFERENCES `users`(`id`) ON DELETE CASCADE)"
],
)
Expand Down Expand Up @@ -279,13 +300,13 @@ def test_can_have_unsigned_columns(self):
blueprint.to_sql(),
[
"CREATE TABLE `users` ("
"`profile_id` INT UNSIGNED NOT NULL, "
"`big_profile_id` BIGINT UNSIGNED NOT NULL, "
"`tiny_profile_id` TINYINT UNSIGNED NOT NULL, "
"`small_profile_id` SMALLINT UNSIGNED NOT NULL, "
"`medium_profile_id` MEDIUMINT UNSIGNED NOT NULL, "
"`profile_id` INT(11) UNSIGNED NOT NULL, "
"`big_profile_id` BIGINT(32) UNSIGNED NOT NULL, "
"`tiny_profile_id` TINYINT(1) UNSIGNED NOT NULL, "
"`small_profile_id` SMALLINT(5) UNSIGNED NOT NULL, "
"`medium_profile_id` MEDIUMINT(7) UNSIGNED NOT NULL, "
"`unsigned_profile_id` INT UNSIGNED NOT NULL, "
"`unsigned_big_profile_id` BIGINT UNSIGNED NOT NULL)"
"`unsigned_big_profile_id` BIGINT(32) UNSIGNED NOT NULL)"
],
)

Expand Down
Loading

0 comments on commit 45b6323

Please sign in to comment.