Browse Source

add partition insert

tumao 4 years ago
parent
commit
0d432a3c90

+ 23 - 4
client/src/components/insert/Container.tsx

@@ -41,6 +41,7 @@ const InsertContainer: FC<InsertContentProps> = ({
   defaultSelectedCollection,
   defaultSelectedPartition,
 
+  partitions = [],
   schema = [],
   handleInsert,
 }) => {
@@ -55,6 +56,7 @@ const InsertContainer: FC<InsertContentProps> = ({
   const [insertStatus, setInsertStauts] = useState<InsertStatusEnum>(
     InsertStatusEnum.init
   );
+  // TODO: add validation
   // const [nextDisabled, setNextDisabled] = useState<boolean>(false);
 
   // selected collection name
@@ -75,6 +77,8 @@ const InsertContainer: FC<InsertContentProps> = ({
   // handle changed table heads
   const [tableHeads, setTableHeads] = useState<string[]>([]);
 
+  const [partitionOptions, setPartitionOptions] = useState<Option[]>([]);
+
   const previewData = useMemo(() => {
     // we only show top 4 results of uploaded csv data
     const end = isContainFieldNames ? 5 : 4;
@@ -101,8 +105,25 @@ const InsertContainer: FC<InsertContentProps> = ({
   }, [collectionValue]);
 
   useEffect(() => {
-    fetchPartition();
-  }, [fetchPartition]);
+    // if not on partitions page, we need to fetch partitions according to selected collection
+    if (partitions.length === 0) {
+      fetchPartition();
+    } else {
+      const options = partitions
+        .map(p => ({
+          label: p._formatName,
+          value: p._name,
+        }))
+        // when there's single selected partition
+        // insert dialog partitions shouldn't selectable
+        .filter(
+          partition =>
+            partition.label === defaultSelectedPartition ||
+            defaultSelectedPartition === ''
+        );
+      setPartitionOptions(options);
+    }
+  }, [partitions, fetchPartition, defaultSelectedPartition]);
 
   const BackIcon = icons.back;
 
@@ -170,8 +191,6 @@ const InsertContainer: FC<InsertContentProps> = ({
     }));
   }, [schema, collectionValue, collections]);
 
-  const [partitionOptions, setPartitionOptions] = useState<Option[]>([]);
-
   const checkUploadFileValidation = (fieldNamesLength: number): boolean => {
     return schemaOptions.length === fieldNamesLength;
   };

+ 3 - 0
client/src/components/insert/Types.ts

@@ -1,4 +1,5 @@
 import { CollectionData } from '../../pages/collections/Types';
+import { PartitionView } from '../../pages/partitions/Types';
 import { FieldData } from '../../pages/schema/Types';
 import { Option } from '../customSelector/Types';
 
@@ -7,6 +8,8 @@ export interface InsertContentProps {
   collections?: CollectionData[];
   // required on partition page since user can't select collection to get schema
   schema?: FieldData[];
+  // required on partition page
+  partitions?: PartitionView[];
 
   // insert default selected collection
   // if default value is not '', collections not selectable

+ 3 - 13
client/src/http/Collection.ts

@@ -1,9 +1,6 @@
 import { ChildrenStatusType, StatusEnum } from '../components/status/Types';
-import {
-  CollectionView,
-  DataType,
-  InsertDataParam,
-} from '../pages/collections/Types';
+import { CollectionView, InsertDataParam } from '../pages/collections/Types';
+import { Field } from '../pages/schema/Types';
 import { IndexState, ShowCollectionsType } from '../types/Milvus';
 import { formatNumber } from '../utils/Common';
 import BaseModel from './BaseModel';
@@ -18,14 +15,7 @@ export class CollectionHttp extends BaseModel implements CollectionView {
   private id!: string;
   private isLoaded!: boolean;
   private schema!: {
-    fields: {
-      data_type: DataType;
-      fieldID: string;
-      type_params: { key: string; value: string }[];
-      is_primary_key: true;
-      name: string;
-      description: string;
-    }[];
+    fields: Field[];
   };
 
   static COLLECTIONS_URL = '/collections';

+ 2 - 0
client/src/pages/collections/Collections.tsx

@@ -151,6 +151,8 @@ const Collections = () => {
     try {
       await CollectionHttp.insertData(collectionName, param);
       await MilvusHttp.flush(collectionName);
+      // update collections
+      fetchData();
       return true;
     } catch (err) {
       return false;

+ 31 - 9
client/src/pages/partitions/Partitions.tsx

@@ -24,6 +24,10 @@ import { parseLocationSearch } from '../../utils/Format';
 import { useInsertDialogHook } from '../../hooks/Dialog';
 import InsertContainer from '../../components/insert/Container';
 import { CollectionHttp } from '../../http/Collection';
+import { FieldHttp } from '../../http/Field';
+import { Field } from '../schema/Types';
+import { InsertDataParam } from '../collections/Types';
+import { MilvusHttp } from '../../http/Milvus';
 
 const useStyles = makeStyles((theme: Theme) => ({
   wrapper: {
@@ -182,9 +186,26 @@ const Partitions: FC<{
     }, 300);
   };
 
-  const handleInsert = useCallback(async (): Promise<boolean> => {
-    return new Promise((resolve, reject) => {});
-  }, []);
+  const handleInsert = async (
+    collectionName: string,
+    partitionName: string,
+    fieldData: any[]
+  ): Promise<boolean> => {
+    const param: InsertDataParam = {
+      partition_names: [partitionName],
+      fields_data: fieldData,
+    };
+    try {
+      await CollectionHttp.insertData(collectionName, param);
+      await MilvusHttp.flush(collectionName);
+      // update partitions
+      fetchPartitions(collectionName);
+
+      return true;
+    } catch (err) {
+      return false;
+    }
+  };
 
   const toolbarConfigs: ToolBarConfig[] = [
     {
@@ -209,27 +230,28 @@ const Partitions: FC<{
       label: btnTrans('insert'),
       onClick: async () => {
         const collection = await fetchCollectionDetail(collectionName);
-        // const schema = collection.schema.fields.map(f => new )
-        console.log('----- collections', collection);
+        const schema = collection.schema.fields.map(
+          (f: Field) => new FieldHttp(f)
+        );
 
         handleInsertDialog(
           <InsertContainer
-            collections={[]}
-            schema={[]}
+            schema={schema}
             defaultSelectedCollection={collectionName}
             defaultSelectedPartition={
               selectedPartitions.length === 1
                 ? selectedPartitions[0]._formatName
                 : ''
             }
+            partitions={partitions}
             handleInsert={handleInsert}
           />
         );
       },
       /**
        * insert validation:
-       * 1. At least 1 available collection
-       * 2. selected collections quantity shouldn't over 1
+       * 1. At least 1 available partition
+       * 2. selected partition quantity shouldn't over 1
        */
       disabled: () => partitions.length === 0 || selectedPartitions.length > 1,
       btnVariant: 'outlined',

+ 9 - 0
client/src/pages/schema/Types.ts

@@ -12,6 +12,15 @@ export enum INDEX_TYPES_ENUM {
   RNSG = 'RNSG',
 }
 
+export interface Field {
+  data_type: DataType;
+  fieldID: string;
+  type_params: { key: string; value: string }[];
+  is_primary_key: true;
+  name: string;
+  description: string;
+}
+
 export interface FieldData {
   _fieldId: string;
   _isPrimaryKey: boolean;