Skip to content

Commit

Permalink
Merge branch 'master' into context_menu
Browse files Browse the repository at this point in the history
  • Loading branch information
pavish committed Mar 25, 2022
2 parents 6319b1e + edd0231 commit acc61ff
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 6 deletions.
13 changes: 13 additions & 0 deletions db/columns/operations/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,14 @@
from db.tables.operations.select import reflect_table_from_oid
from db.types.operations.cast import get_supported_alter_column_types

COLUMN_NAME_TEMPLATE = 'Column'


def create_column(engine, table_oid, column_data):
table = reflect_table_from_oid(table_oid, engine)
column_name = column_data.get(NAME, '').strip()
if column_name == '':
column_data[NAME] = gen_col_name(table)
column_type = column_data.get(TYPE, column_data.get("type"))
column_type_options = column_data.get("type_options", {})
column_nullable = column_data.get(NULLABLE, True)
Expand Down Expand Up @@ -67,6 +73,13 @@ def create_column(engine, table_oid, column_data):
)


def gen_col_name(table):
base_name = COLUMN_NAME_TEMPLATE
col_num = len(table.c)
name = f'{base_name} {col_num}'
return name


def _gen_col_name(table, column_name):
num = 1
new_column_name = f"{column_name}_{num}"
Expand Down
74 changes: 73 additions & 1 deletion db/tests/columns/operations/test_create.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
from sqlalchemy import Integer, Column, Table, MetaData, Numeric, UniqueConstraint

from db.columns.operations.create import create_column, duplicate_column
from db.columns.operations.create import create_column, duplicate_column, gen_col_name
from db.columns.operations.select import get_column_attnum_from_name, get_column_default
from db.tables.operations.select import get_oid_from_table, reflect_table_from_oid
from db.constraints.operations.select import get_column_constraints
Expand Down Expand Up @@ -357,3 +357,75 @@ def test_duplicate_column_default(engine_with_schema, copy_data, copy_constraint
assert default == expt_default
else:
assert default is None


def test_create_column_accepts_column_data_without_name_attribute(engine_email_type):
engine, schema = engine_email_type
table_name = "atableone"
initial_column_name = "Column 0"
expected_column_name = "Column 1"
table = Table(
table_name,
MetaData(bind=engine, schema=schema),
Column(initial_column_name, Integer),
)
table.create()
table_oid = get_oid_from_table(table_name, schema, engine)
column_data = {"type": "BOOLEAN"}
created_col = create_column(engine, table_oid, column_data)
altered_table = reflect_table_from_oid(table_oid, engine)
assert len(altered_table.columns) == 2
assert created_col.name == expected_column_name


def test_create_column_accepts_column_data_with_name_as_empty_string(engine_email_type):
engine, schema = engine_email_type
table_name = "atableone"
initial_column_name = "Column 0"
expected_column_name = "Column 1"
table = Table(
table_name,
MetaData(bind=engine, schema=schema),
Column(initial_column_name, Integer),
)
table.create()
table_oid = get_oid_from_table(table_name, schema, engine)
column_data = {"name": "", "type": "BOOLEAN"}
created_col = create_column(engine, table_oid, column_data)
altered_table = reflect_table_from_oid(table_oid, engine)
assert len(altered_table.columns) == 2
assert created_col.name == expected_column_name


def test_generate_column_name(engine_email_type):
engine, schema = engine_email_type
name_set = {
'Center',
'Status',
'Case Number',
'Patent Number',
'Application SN',
'Title',
'Patent Expiration Date',
''
}
table_name = "atableone"
initial_column_name = "id"
table = Table(
table_name,
MetaData(bind=engine, schema=schema),
Column(initial_column_name, Integer),
)
table.create()
table_oid = get_oid_from_table(table_name, schema, engine)
for name in name_set:
column_data = {"name": name, "type": "BOOLEAN"}
create_column(engine, table_oid, column_data)
altered_table = reflect_table_from_oid(table_oid, engine)
n = len(name_set) + 1
# Expected column name should be 'Column n'
# where n is length of number of columns already in the table
expected_column_name = f"Column {n}"
generated_column_name = gen_col_name(altered_table)
assert len(altered_table.columns) == n
assert generated_column_name == expected_column_name
4 changes: 2 additions & 2 deletions mathesar/api/serializers/columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class Meta(SimpleColumnSerializer.Meta):
)
model_fields = ('display_options',)

name = serializers.CharField(required=False)
name = serializers.CharField(required=False, allow_blank=True)

# From scratch fields
type = serializers.CharField(source='plain_type', required=False)
Expand All @@ -116,7 +116,7 @@ class Meta(SimpleColumnSerializer.Meta):

def validate(self, data):
if not self.partial:
from_scratch_required_fields = ['name', 'type']
from_scratch_required_fields = ['type']
from_scratch_specific_fields = ['type', 'nullable', 'primary_key']
from_dupe_required_fields = ['source_column']
from_dupe_specific_fields = ['source_column', 'copy_source_data',
Expand Down
47 changes: 44 additions & 3 deletions mathesar/tests/api/test_column_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,49 @@ def test_column_create_some_parameters(column_test_table, client):
assert response_data['field'] == "type"


def test_column_create_no_name_parameter(column_test_table, client):
cache.clear()
type_ = "BOOLEAN"
num_columns = len(column_test_table.sa_columns)
generated_name = f"Column {num_columns}"
data = {
"type": type_
}
response = client.post(
f"/api/db/v0/tables/{column_test_table.id}/columns/", data=data
)
assert response.status_code == 201
new_columns_response = client.get(
f"/api/db/v0/tables/{column_test_table.id}/columns/"
)
assert new_columns_response.json()["count"] == num_columns + 1
actual_new_col = new_columns_response.json()["results"][-1]
assert actual_new_col["name"] == generated_name
assert actual_new_col["type"] == type_


def test_column_create_name_parameter_empty(column_test_table, client):
cache.clear()
name = ""
type_ = "BOOLEAN"
num_columns = len(column_test_table.sa_columns)
generated_name = f"Column {num_columns}"
data = {
"name": name, "type": type_
}
response = client.post(
f"/api/db/v0/tables/{column_test_table.id}/columns/", data=data
)
assert response.status_code == 201
new_columns_response = client.get(
f"/api/db/v0/tables/{column_test_table.id}/columns/"
)
assert new_columns_response.json()["count"] == num_columns + 1
actual_new_col = new_columns_response.json()["results"][-1]
assert actual_new_col["name"] == generated_name
assert actual_new_col["type"] == type_


def test_column_update_name(column_test_table, client):
cache.clear()
name = "updatedname"
Expand Down Expand Up @@ -754,6 +797,4 @@ def test_column_duplicate_no_parameters(column_test_table, client):
response_data = response.json()
assert response.status_code == 400
assert response_data[0]["message"] == "This field is required."
assert response_data[0]["field"] == "name"
assert response_data[1]["message"] == "This field is required."
assert response_data[1]["field"] == "type"
assert response_data[0]["field"] == "type"

0 comments on commit acc61ff

Please sign in to comment.