1
0
mirror of https://github.com/ManyakRus/crud_generator.git synced 2024-12-18 23:47:38 +02:00
crud_generator/internal/postgres/postgres.go
Nikitin Aleksandr b7446dc946 новый
2023-09-28 17:45:44 +03:00

230 lines
5.9 KiB
Go

package postgres
import (
"context"
"errors"
"fmt"
"github.com/ManyakRus/crud_generator/internal/config"
"github.com/ManyakRus/crud_generator/internal/types"
"github.com/ManyakRus/starter/contextmain"
"github.com/ManyakRus/starter/log"
"github.com/ManyakRus/starter/postgres_gorm"
"gorm.io/gorm"
"strings"
"time"
)
type TableColumn struct {
TableName string `json:"table_name" gorm:"column:table_name;default:''"`
ColumnName string `json:"column_name" gorm:"column:column_name;default:''"`
ColumnType string `json:"type_name" gorm:"column:type_name;default:''"`
ColumnIsIdentity string `json:"is_identity" gorm:"column:is_identity;default:''"`
ColumnDescription string `json:"description" gorm:"column:description;default:''"`
ColumnTableKey string `json:"table_key" gorm:"column:table_key;default:''"`
ColumnColumnKey string `json:"column_key" gorm:"column:column_key;default:''"`
}
// FillMapTable - возвращает массив MassTable данными из БД
func FillMapTable() (map[string]*types.Table, error) {
var err error
//MassTable := make([]types.Table, 0)
MapTable := make(map[string]*types.Table, 0)
TextSQL := `
drop table if exists temp_keys;
CREATE TEMPORARY TABLE temp_keys (table_from text, column_from text, table_to text, column_to text);
------------------------------------------- Все внешние ключи ------------------------------
insert into temp_keys
SELECT
(select r.relname from pg_class r where r.oid = c.conrelid) as table_from,
UNNEST((select array_agg(attname) from pg_attribute where attrelid = c.conrelid and array[attnum] <@ c.conkey)) as column_from,
(select r.relname from pg_class r where r.oid = c.confrelid) as table_to,
a.attname as column_to
FROM
pg_constraint c
join
pg_attribute a
on
c.confrelid=a.attrelid and a.attnum = ANY(confkey)
WHERE 1=1
--and c.confrelid = (select oid from pg_class where relname = 'debt_types')
AND c.confrelid!=c.conrelid
;
------------------------------------------- Все таблицы и колонки ------------------------------
SELECT
c.table_name,
c.column_name,
c.udt_name as type_name,
c.is_identity as is_identity,
COALESCE(pgd.description, '') as description,
COALESCE(keys.table_to, '') as table_key,
COALESCE(keys.column_to, '') as column_key
FROM
pg_catalog.pg_statio_all_tables as st
inner join
pg_catalog.pg_description pgd
on
pgd.objoid = st.relid
right join
information_schema.columns c
on
pgd.objsubid = c.ordinal_position
and c.table_schema = st.schemaname
and c.table_name = st.relname
LEFT JOIN --внешние ключи
temp_keys as keys
ON
keys.table_from = c.table_name
and keys.column_from = c.column_name
LEFT JOIN --вьюхи
INFORMATION_SCHEMA.views as v
ON
v.table_schema = 'public'
and v.table_name = c.table_name
where 1=1
and c.table_schema='public'
and v.table_name is null
--INCLUDE_TABLES
--EXCLUDE_TABLES
order by
table_name,
is_identity desc,
column_name
`
SCHEMA := strings.Trim(postgres_gorm.Settings.DB_SCHEMA, " ")
if SCHEMA != "" {
TextSQL = strings.ReplaceAll(TextSQL, "public", SCHEMA)
}
if config.Settings.INCLUDE_TABLES != "" {
TextSQL = strings.ReplaceAll(TextSQL, "--INCLUDE_TABLES", "and c.table_name ~* '"+config.Settings.INCLUDE_TABLES+"'")
}
if config.Settings.EXCLUDE_TABLES != "" {
TextSQL = strings.ReplaceAll(TextSQL, "--EXCLUDE_TABLES", "and c.table_name !~* '"+config.Settings.EXCLUDE_TABLES+"'")
}
//соединение
ctxMain := contextmain.GetContext()
ctx, ctxCancelFunc := context.WithTimeout(ctxMain, time.Second*60)
defer ctxCancelFunc()
db := postgres_gorm.GetConnection()
db.WithContext(ctx)
//запрос
//запустим все запросы отдельно
var tx *gorm.DB
sqlSlice := strings.Split(TextSQL, ";")
len1 := len(sqlSlice)
for i, TextSQL1 := range sqlSlice {
//batch.Queue(TextSQL1)
if i == len1-1 {
tx = db.Raw(TextSQL1)
} else {
tx = db.Exec(TextSQL1)
//rows.Close()
}
err = tx.Error
if err != nil {
log.Panic("DB.Raw() error:", err)
}
}
//tx := db.Raw(TextSQL)
//err = tx.Error
//if err != nil {
// sError := fmt.Sprint("db.Raw() error: ", err)
// log.Panicln(sError)
// return MassTable, err
//}
//ответ в структуру
MassTableColumn := make([]TableColumn, 0)
tx = tx.Scan(&MassTableColumn)
err = tx.Error
if err != nil {
sError := fmt.Sprint("Get_error() error: ", err)
log.Panicln(sError)
return MapTable, err
}
//проверка 0 строк
if tx.RowsAffected == 0 {
sError := fmt.Sprint("db.Raw() RowsAffected =0 ")
log.Warn(sError)
err = errors.New(sError)
//log.Panicln(sError)
return MapTable, err
}
//заполним MapTable
MapColumns := make(map[string]types.Column, 0)
OrderNumberColumn := 0
OrderNumberTable := 0
TableName0 := ""
Table1 := CreateTable()
for _, v := range MassTableColumn {
if v.TableName != TableName0 {
OrderNumberColumn = 0
Table1.MapColumns = MapColumns
MapColumns = make(map[string]types.Column, 0)
if TableName0 != "" {
//MassTable = append(MassTable, Table1)
MapTable[TableName0] = Table1
OrderNumberTable++
}
Table1 = CreateTable()
Table1.Name = v.TableName
Table1.OrderNumber = OrderNumberTable
}
Column1 := types.Column{}
Column1.Name = v.ColumnName
Column1.Type = v.ColumnType
if v.ColumnIsIdentity == "YES" {
Column1.Is_identity = true
}
Column1.Description = v.ColumnDescription
Column1.OrderNumber = OrderNumberColumn
Column1.TableKey = v.ColumnTableKey
Column1.ColumnKey = v.ColumnColumnKey
MapColumns[v.ColumnName] = Column1
//Table1.Columns = append(Table1.Columns, Column1)
OrderNumberColumn++
TableName0 = v.TableName
}
if Table1.Name != "" {
Table1.MapColumns = MapColumns
MapTable[TableName0] = Table1
}
return MapTable, err
}
func CreateTable() *types.Table {
Otvet := &types.Table{}
Otvet.MapColumns = make(map[string]types.Column, 0)
return Otvet
}