@@ -54,32 +54,89 @@ class MongoConnector extends AdminForthBaseConnector implements IAdminForthDataS
5454 return collections . map ( col => col . name ) ;
5555 }
5656
57- async getAllColumnsInTable ( collectionName : string ) : Promise < Array < string > > {
57+ async getAllColumnsInTable ( collectionName : string ) : Promise < Array < { name : string ; type ?: string ; isPrimaryKey ?: boolean } > > {
5858
5959 const sampleDocs = await this . client . db ( ) . collection ( collectionName ) . find ( { } ) . sort ( { _id : - 1 } ) . limit ( 100 ) . toArray ( ) ;
60-
61- const fieldSet = new Set < string > ( ) ;
62-
60+
61+ const fieldTypes = new Map < string , Set < string > > ( ) ;
62+
63+ function detectType ( value : any ) : string {
64+ if ( value === null || value === undefined ) return 'string' ;
65+ if ( typeof value === 'string' ) return 'string' ;
66+ if ( typeof value === 'boolean' ) return 'boolean' ;
67+ if ( typeof value === 'number' ) {
68+ return Number . isInteger ( value ) ? 'integer' : 'float' ;
69+ }
70+ if ( value instanceof Date ) return 'datetime' ;
71+ if ( typeof value === 'object' ) return 'json' ;
72+ return 'string' ;
73+ }
74+
75+ function addType ( name : string , type : string ) {
76+ if ( ! fieldTypes . has ( name ) ) {
77+ fieldTypes . set ( name , new Set ( ) ) ;
78+ }
79+ fieldTypes . get ( name ) ! . add ( type ) ;
80+ }
81+
6382 function flattenObject ( obj : any , prefix = '' ) {
64- Object . entries ( obj ) . forEach ( ( [ key , value ] ) => {
83+ Object . entries ( obj ) . forEach ( ( [ key , value ] ) => {
6584 const fullKey = prefix ? `${ prefix } .${ key } ` : key ;
85+
6686 if ( fullKey . startsWith ( '_id.' ) && typeof value !== 'string' && typeof value !== 'number' ) {
67- return ;
68- }
69- if ( value && typeof value === 'object' && ! Array . isArray ( value ) && ! ( value instanceof Date ) ) {
70- flattenObject ( value , fullKey ) ;
87+ return ;
88+ }
89+
90+ if (
91+ value instanceof Buffer ||
92+ ( value && typeof value === 'object' && ( value as any ) . _bsontype === 'Decimal128' )
93+ ) {
94+ addType ( fullKey , 'json' ) ;
95+ return ;
96+ }
97+
98+ if (
99+ value &&
100+ typeof value === 'object' &&
101+ ! Array . isArray ( value ) &&
102+ ! ( value instanceof Date )
103+ ) {
104+ // Вместо рекурсивного прохода — просто добавляем этот объект целиком как json
105+ addType ( fullKey , 'json' ) ;
71106 } else {
72- fieldSet . add ( fullKey ) ;
107+ addType ( fullKey , detectType ( value ) ) ;
73108 }
74- } ) ;
109+ } ) ;
75110 }
76-
111+
77112 for ( const doc of sampleDocs ) {
78- flattenObject ( doc ) ;
113+ flattenObject ( doc ) ;
79114 }
80-
81- return Array . from ( fieldSet ) ;
82- }
115+
116+ return Array . from ( fieldTypes . entries ( ) ) . map ( ( [ name , types ] ) => {
117+ const primaryKey = name === '_id' ;
118+
119+ const priority = [ 'datetime' , 'date' , 'integer' , 'float' , 'boolean' , 'json' , 'string' ] ;
120+
121+ const matched = priority . find ( t => types . has ( t ) ) || 'string' ;
122+
123+ const typeMap : Record < string , string > = {
124+ string : 'STRING' ,
125+ integer : 'INTEGER' ,
126+ float : 'FLOAT' ,
127+ boolean : 'BOOLEAN' ,
128+ datetime : 'DATETIME' ,
129+ date : 'DATE' ,
130+ json : 'JSON' ,
131+ } ;
132+
133+ return {
134+ name,
135+ type : typeMap [ matched ] ?? 'STRING' ,
136+ ...( primaryKey ? { isPrimaryKey : true } : { } ) ,
137+ } ;
138+ } ) ;
139+ }
83140
84141
85142 async discoverFields ( resource ) {
0 commit comments