From 3f3742122f28b5a49c85aee1eb70db8d9573f80b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hitalo=20de=20Jesus=20do=20Ros=C3=A1rio=20Souza?= <63821277+enghitalo@users.noreply.github.com> Date: Wed, 13 Jul 2022 12:03:30 -0300 Subject: [PATCH] orm: sql type in struct by attribute (#14919) --- vlib/mysql/mysql_orm_test.v | 90 +++++++++++++++++++++++++++++++++++-- vlib/orm/README.md | 1 + vlib/orm/orm.v | 14 ++++-- 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/vlib/mysql/mysql_orm_test.v b/vlib/mysql/mysql_orm_test.v index 2acb182b52..49bc406d24 100644 --- a/vlib/mysql/mysql_orm_test.v +++ b/vlib/mysql/mysql_orm_test.v @@ -1,6 +1,24 @@ import orm import mysql +struct TestCustomSqlType { + id int [primary; sql: serial] + custom string [sql_type: 'TEXT'] + custom1 string [sql_type: 'VARCHAR(191)'] + custom2 string [sql_type: 'datetime(3)'] + custom3 string [sql_type: 'MEDIUMINT'] + custom4 string [sql_type: 'DATETIME'] + custom5 string [sql_type: 'datetime'] +} + +struct TestCustomWrongSqlType { + id int [primary; sql: serial] + custom string + custom1 string [sql_type: 'VARCHAR'] + custom2 string [sql_type: 'money'] + custom3 string [sql_type: 'xml'] +} + fn test_mysql_orm() { mut mdb := mysql.Connection{ host: 'localhost' @@ -29,7 +47,7 @@ fn test_mysql_orm() { }, orm.TableField{ name: 'name' - typ: 18 + typ: 20 attrs: [] }, orm.TableField{ @@ -47,11 +65,11 @@ fn test_mysql_orm() { table: 'Test' has_where: true fields: ['id', 'name', 'age'] - types: [7, 18, 8] + types: [7, 20, 8] }, orm.QueryData{}, orm.QueryData{ fields: ['name', 'age'] data: [orm.Primitive('Louis'), i64(101)] - types: [18, 8] + types: [20, 8] is_and: [true, true] kinds: [.eq, .eq] }) or { panic(err) } @@ -75,3 +93,69 @@ fn test_mysql_orm() { assert age == 101 } } + +fn test_orm() { + mut db := mysql.Connection{ + host: 'localhost' + port: 3306 + username: 'root' + password: '' + dbname: 'mysql' + } + + db.connect() or { + println(err) + panic(err) + } + + sql db { + create table TestCustomSqlType + } + + mut result_custom_sql := db.query(" + SELECT DATA_TYPE, COLUMN_TYPE + FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_NAME = 'TestCustomSqlType' + ORDER BY ORDINAL_POSITION + ") or { + println(err) + panic(err) + } + + information_schema_custom_sql := [ + { + 'DATA_TYPE': 'bigint' + 'COLUMN_TYPE': 'bigint unsigned' + }, + { + 'DATA_TYPE': 'text' + 'COLUMN_TYPE': 'text' + }, + { + 'DATA_TYPE': 'varchar' + 'COLUMN_TYPE': 'varchar(191)' + }, + { + 'DATA_TYPE': 'datetime' + 'COLUMN_TYPE': 'datetime(3)' + }, + { + 'DATA_TYPE': 'mediumint' + 'COLUMN_TYPE': 'mediumint' + }, + { + 'DATA_TYPE': 'datetime' + 'COLUMN_TYPE': 'datetime' + }, + { + 'DATA_TYPE': 'datetime' + 'COLUMN_TYPE': 'datetime' + }, + ] + + assert result_custom_sql.maps() == information_schema_custom_sql + + sql db { + drop table TestCustomSqlType + } +} diff --git a/vlib/orm/README.md b/vlib/orm/README.md index b19ee4331e..7ad71a30b2 100644 --- a/vlib/orm/README.md +++ b/vlib/orm/README.md @@ -14,6 +14,7 @@ - `[skip]` field will be skipped - `[sql: type]` where `type` is a V type such as `int` or `f64`, or special type `serial` - `[sql: 'name']` sets a custom column name for the field +- `[sql_type: 'SQL TYPE']` sets the sql type which is used in sql ## Usage diff --git a/vlib/orm/orm.v b/vlib/orm/orm.v index 04d869efc3..e24a2526db 100644 --- a/vlib/orm/orm.v +++ b/vlib/orm/orm.v @@ -363,6 +363,10 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int, mut unique_len := 0 // mut fkey := '' mut field_name := sql_field_name(field) + mut ctyp := sql_from_v(sql_field_type(field)) or { + field_name = '${field_name}_id' + sql_from_v(7)? + } for attr in field.attrs { match attr.name { 'primary' { @@ -387,6 +391,12 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int, 'skip' { is_skip = true } + 'sql_type' { + if attr.kind != .string { + return error("sql_type attribute need be string. Try [sql_type: '$attr.arg'] instead of [sql_type: $attr.arg]") + } + ctyp = attr.arg + } /*'fkey' { if attr.arg != '' { if attr.kind == .string { @@ -402,10 +412,6 @@ pub fn orm_table_gen(table string, q string, defaults bool, def_unique_len int, continue } mut stmt := '' - mut ctyp := sql_from_v(sql_field_type(field)) or { - field_name = '${field_name}_id' - sql_from_v(7)? - } if ctyp == '' { return error('Unknown type ($field.typ) for field $field.name in struct $table') }