diff --git a/migration/i8.2/oracle/202104162211_IDEMPIERE-4762.sql b/migration/i8.2/oracle/202104162211_IDEMPIERE-4762.sql new file mode 100644 index 0000000000..c0e17c5cc5 --- /dev/null +++ b/migration/i8.2/oracle/202104162211_IDEMPIERE-4762.sql @@ -0,0 +1,147 @@ +SET SQLBLANKLINES ON +SET DEFINE OFF + +-- IDEMPIERE-4762 Add AD_StorageProvider_ID to AD_Attachment (FHCA-1165) +-- Apr 16, 2021, 9:52:15 PM CEST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214420,0,'Storage Provider',254,'AD_StorageProvider_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_DATE('2021-04-16 21:52:15','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-04-16 21:52:15','YYYY-MM-DD HH24:MI:SS'),100,200238,'N','N','D','N','N','N','Y','c6ce4bd2-7688-451c-89bd-ac02866671fb','Y',0,'N','N','N') +; + +-- Apr 16, 2021, 9:53:14 PM CEST +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (206604,'Storage Provider',173,214420,'Y',22,100,'N','N','N','N',0,0,'Y',TO_DATE('2021-04-16 21:53:14','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-04-16 21:53:14','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','c1e37d25-d4ed-4681-a102-34be0dc1b5a8','Y',100,2) +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=10, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=960 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=20, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=2039 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=30, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=963 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET IsDisplayed='Y', SeqNo=40, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, XPosition=5, IsToolbarButton=NULL,Updated=TO_DATE('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=964 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=50, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=3819 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=60, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=10074 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=70, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206604 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET IsDisplayed='Y', SeqNo=80, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, XPosition=5, IsToolbarButton=NULL,Updated=TO_DATE('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=961 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=0, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204470 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=0, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_DATE('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=959 +; + +-- Apr 16, 2021, 9:55:50 PM CEST +UPDATE AD_Column SET FKConstraintName='ADStorageProvider_ADAttachment', FKConstraintType='N',Updated=TO_DATE('2021-04-16 21:55:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214420 +; + +-- Apr 16, 2021, 9:55:50 PM CEST +ALTER TABLE AD_Attachment ADD AD_StorageProvider_ID NUMBER(10) DEFAULT NULL +; + +-- Apr 16, 2021, 9:55:50 PM CEST +ALTER TABLE AD_Attachment ADD CONSTRAINT ADStorageProvider_ADAttachment FOREIGN KEY (AD_StorageProvider_ID) REFERENCES ad_storageprovider(ad_storageprovider_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Apr 16, 2021, 11:17:37 PM CEST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214421,0,'Storage Provider',461,'AD_StorageProvider_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_DATE('2021-04-16 23:17:37','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-04-16 23:17:37','YYYY-MM-DD HH24:MI:SS'),100,200238,'N','N','D','N','N','N','Y','ffac0527-d6d3-4a92-84cb-c15f7ac076c5','Y',0,'N','N','N') +; + +-- Apr 16, 2021, 11:17:39 PM CEST +UPDATE AD_Column SET FKConstraintName='ADStorageProvider_ADImage', FKConstraintType='N',Updated=TO_DATE('2021-04-16 23:17:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214421 +; + +-- Apr 16, 2021, 11:17:39 PM CEST +ALTER TABLE AD_Image ADD AD_StorageProvider_ID NUMBER(10) DEFAULT NULL +; + +-- Apr 16, 2021, 11:17:39 PM CEST +ALTER TABLE AD_Image ADD CONSTRAINT ADStorageProvider_ADImage FOREIGN KEY (AD_StorageProvider_ID) REFERENCES ad_storageprovider(ad_storageprovider_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Apr 16, 2021, 11:18:35 PM CEST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (214422,0,'Storage Provider',754,'AD_StorageProvider_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_DATE('2021-04-16 23:18:34','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-04-16 23:18:34','YYYY-MM-DD HH24:MI:SS'),100,200238,'N','N','D','N','N','N','Y','d15193c9-69cb-48de-94b4-5afeb82f405a','Y',0,'N','N','N','N') +; + +-- Apr 16, 2021, 11:18:37 PM CEST +UPDATE AD_Column SET FKConstraintName='ADStorageProvider_ADArchive', FKConstraintType='N',Updated=TO_DATE('2021-04-16 23:18:37','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214422 +; + +-- Apr 16, 2021, 11:18:37 PM CEST +ALTER TABLE AD_Archive ADD AD_StorageProvider_ID NUMBER(10) DEFAULT NULL +; + +-- Apr 16, 2021, 11:18:37 PM CEST +ALTER TABLE AD_Archive ADD CONSTRAINT ADStorageProvider_ADArchive FOREIGN KEY (AD_StorageProvider_ID) REFERENCES ad_storageprovider(ad_storageprovider_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Apr 21, 2021, 5:36:53 PM CEST +UPDATE AD_Process_Para SET SeqNo=90,Updated=TO_DATE('2021-04-21 17:36:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200293 +; + +-- Apr 21, 2021, 5:37:39 PM CEST +UPDATE AD_Process_Para SET DefaultValue='Y',Updated=TO_DATE('2021-04-21 17:37:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200290 +; + +-- Apr 21, 2021, 5:37:43 PM CEST +UPDATE AD_Process_Para SET DefaultValue='Y',Updated=TO_DATE('2021-04-21 17:37:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200291 +; + +-- Apr 21, 2021, 5:37:46 PM CEST +UPDATE AD_Process_Para SET DefaultValue='Y',Updated=TO_DATE('2021-04-21 17:37:46','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200292 +; + +-- Apr 21, 2021, 5:39:08 PM CEST +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203483,0,0,'Y',TO_DATE('2021-04-21 17:38:43','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-04-21 17:38:43','YYYY-MM-DD HH24:MI:SS'),100,'IsMigrateData','Migrate Data',NULL,NULL,'Migrate Data','D','cc8e6b76-fd73-4309-8fc6-2d9ead66d39d') +; + +-- Apr 21, 2021, 5:39:16 PM CEST +INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted,IsAutocomplete) VALUES (200340,0,0,'Y',TO_DATE('2021-04-21 17:39:15','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-04-21 17:39:15','YYYY-MM-DD HH24:MI:SS'),100,'Migrate Data',200117,70,20,'N',1,'Y','Y','IsMigrateData','Y','D',203483,'c060a763-cdf5-4b44-9486-5be5fb523674','N','N') +; + +-- Apr 21, 2021, 5:42:35 PM CEST +INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,Help,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted,MandatoryLogic,IsAutocomplete) VALUES (200341,0,0,'Y',TO_DATE('2021-04-21 17:42:35','YYYY-MM-DD HH24:MI:SS'),100,TO_DATE('2021-04-21 17:42:35','YYYY-MM-DD HH24:MI:SS'),100,'Record ID','Direct internal record ID','The Record ID is the internal unique identifier of a record. Please note that zooming to the record may not be successful for Orders, Invoices and Shipment/Receipts as sometimes the Sales Order type is not known.',200117,80,11,'Y',22,'N','Record_ID','Y','D',538,'c65e1cd9-1c1b-450c-a789-58feb9b7afe0','N',NULL,'N') +; + +-- Apr 21, 2021, 5:54:28 PM CEST +UPDATE AD_Process SET Help='

WARNING: This process can be destructive, so please be sure that you have a backup of the database, as well as a backup of your old storage provider.

+ +

The process migrates files between storage providers.

+ + + +

In case of failure or timeout, the process can be launched again, it commits on every file migrated.

',Updated=TO_DATE('2021-04-21 17:54:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200117 +; + +-- set providers with actual values from client +UPDATE ad_attachment a SET ad_storageprovider_id = (SELECT ci.ad_storageprovider_id FROM ad_clientinfo ci WHERE ci.ad_client_id=a.ad_client_id) +WHERE a.ad_client_id IN (SELECT ad_client_id FROM ad_clientinfo WHERE ad_storageprovider_id IS NOT NULL); + +UPDATE ad_image i SET ad_storageprovider_id = (SELECT ci.storageimage_id FROM ad_clientinfo ci WHERE ci.ad_client_id=i.ad_client_id) +WHERE ad_client_id IN (SELECT ad_client_id FROM ad_clientinfo WHERE storageimage_id IS NOT NULL); + +UPDATE ad_archive a SET ad_storageprovider_id = (SELECT ci.storagearchive_id FROM ad_clientinfo ci WHERE ci.ad_client_id=a.ad_client_id) +WHERE ad_client_id IN (SELECT ad_client_id FROM ad_clientinfo WHERE storagearchive_id IS NOT NULL); + +SELECT register_migration_script('202104162211_IDEMPIERE-4762.sql') FROM dual +; + diff --git a/migration/i8.2/postgresql/202104162211_IDEMPIERE-4762.sql b/migration/i8.2/postgresql/202104162211_IDEMPIERE-4762.sql new file mode 100644 index 0000000000..90f00082e2 --- /dev/null +++ b/migration/i8.2/postgresql/202104162211_IDEMPIERE-4762.sql @@ -0,0 +1,144 @@ +-- IDEMPIERE-4762 Add AD_StorageProvider_ID to AD_Attachment (FHCA-1165) +-- Apr 16, 2021, 9:52:15 PM CEST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214420,0,'Storage Provider',254,'AD_StorageProvider_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2021-04-16 21:52:15','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-04-16 21:52:15','YYYY-MM-DD HH24:MI:SS'),100,200238,'N','N','D','N','N','N','Y','c6ce4bd2-7688-451c-89bd-ac02866671fb','Y',0,'N','N','N') +; + +-- Apr 16, 2021, 9:53:14 PM CEST +INSERT INTO AD_Field (AD_Field_ID,Name,AD_Tab_ID,AD_Column_ID,IsDisplayed,DisplayLength,SeqNo,IsSameLine,IsHeading,IsFieldOnly,IsEncrypted,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,IsReadOnly,IsCentrallyMaintained,EntityType,AD_Field_UU,IsDisplayedGrid,SeqNoGrid,ColumnSpan) VALUES (206604,'Storage Provider',173,214420,'Y',22,100,'N','N','N','N',0,0,'Y',TO_TIMESTAMP('2021-04-16 21:53:14','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-04-16 21:53:14','YYYY-MM-DD HH24:MI:SS'),100,'N','Y','D','c1e37d25-d4ed-4681-a102-34be0dc1b5a8','Y',100,2) +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=10, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=960 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=20, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=2039 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=30, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=963 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET IsDisplayed='Y', SeqNo=40, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, XPosition=5, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=964 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=50, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=3819 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=60, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=10074 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=70, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=206604 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET IsDisplayed='Y', SeqNo=80, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, XPosition=5, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=961 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=0, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=204470 +; + +-- Apr 16, 2021, 9:53:53 PM CEST +UPDATE AD_Field SET SeqNo=0, AD_Reference_Value_ID=NULL, AD_Val_Rule_ID=NULL, IsToolbarButton=NULL,Updated=TO_TIMESTAMP('2021-04-16 21:53:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Field_ID=959 +; + +-- Apr 16, 2021, 9:55:50 PM CEST +UPDATE AD_Column SET FKConstraintName='ADStorageProvider_ADAttachment', FKConstraintType='N',Updated=TO_TIMESTAMP('2021-04-16 21:55:50','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214420 +; + +-- Apr 16, 2021, 9:55:50 PM CEST +ALTER TABLE AD_Attachment ADD COLUMN AD_StorageProvider_ID NUMERIC(10) DEFAULT NULL +; + +-- Apr 16, 2021, 9:55:50 PM CEST +ALTER TABLE AD_Attachment ADD CONSTRAINT ADStorageProvider_ADAttachment FOREIGN KEY (AD_StorageProvider_ID) REFERENCES ad_storageprovider(ad_storageprovider_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Apr 16, 2021, 11:17:37 PM CEST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,IsHtml) VALUES (214421,0,'Storage Provider',461,'AD_StorageProvider_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2021-04-16 23:17:37','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-04-16 23:17:37','YYYY-MM-DD HH24:MI:SS'),100,200238,'N','N','D','N','N','N','Y','ffac0527-d6d3-4a92-84cb-c15f7ac076c5','Y',0,'N','N','N') +; + +-- Apr 16, 2021, 11:17:39 PM CEST +UPDATE AD_Column SET FKConstraintName='ADStorageProvider_ADImage', FKConstraintType='N',Updated=TO_TIMESTAMP('2021-04-16 23:17:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214421 +; + +-- Apr 16, 2021, 11:17:39 PM CEST +ALTER TABLE AD_Image ADD COLUMN AD_StorageProvider_ID NUMERIC(10) DEFAULT NULL +; + +-- Apr 16, 2021, 11:17:39 PM CEST +ALTER TABLE AD_Image ADD CONSTRAINT ADStorageProvider_ADImage FOREIGN KEY (AD_StorageProvider_ID) REFERENCES ad_storageprovider(ad_storageprovider_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Apr 16, 2021, 11:18:35 PM CEST +INSERT INTO AD_Column (AD_Column_ID,Version,Name,AD_Table_ID,ColumnName,FieldLength,IsKey,IsParent,IsMandatory,IsTranslated,IsIdentifier,SeqNo,IsEncrypted,AD_Reference_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,AD_Element_ID,IsUpdateable,IsSelectionColumn,EntityType,IsSyncDatabase,IsAlwaysUpdateable,IsAutocomplete,IsAllowLogging,AD_Column_UU,IsAllowCopy,SeqNoSelection,IsToolbarButton,IsSecure,FKConstraintType,IsHtml) VALUES (214422,0,'Storage Provider',754,'AD_StorageProvider_ID',22,'N','N','N','N','N',0,'N',19,0,0,'Y',TO_TIMESTAMP('2021-04-16 23:18:34','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-04-16 23:18:34','YYYY-MM-DD HH24:MI:SS'),100,200238,'N','N','D','N','N','N','Y','d15193c9-69cb-48de-94b4-5afeb82f405a','Y',0,'N','N','N','N') +; + +-- Apr 16, 2021, 11:18:37 PM CEST +UPDATE AD_Column SET FKConstraintName='ADStorageProvider_ADArchive', FKConstraintType='N',Updated=TO_TIMESTAMP('2021-04-16 23:18:37','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Column_ID=214422 +; + +-- Apr 16, 2021, 11:18:37 PM CEST +ALTER TABLE AD_Archive ADD COLUMN AD_StorageProvider_ID NUMERIC(10) DEFAULT NULL +; + +-- Apr 16, 2021, 11:18:37 PM CEST +ALTER TABLE AD_Archive ADD CONSTRAINT ADStorageProvider_ADArchive FOREIGN KEY (AD_StorageProvider_ID) REFERENCES ad_storageprovider(ad_storageprovider_id) DEFERRABLE INITIALLY DEFERRED +; + +-- Apr 21, 2021, 5:36:53 PM CEST +UPDATE AD_Process_Para SET SeqNo=90,Updated=TO_TIMESTAMP('2021-04-21 17:36:53','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200293 +; + +-- Apr 21, 2021, 5:37:39 PM CEST +UPDATE AD_Process_Para SET DefaultValue='Y',Updated=TO_TIMESTAMP('2021-04-21 17:37:39','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200290 +; + +-- Apr 21, 2021, 5:37:43 PM CEST +UPDATE AD_Process_Para SET DefaultValue='Y',Updated=TO_TIMESTAMP('2021-04-21 17:37:43','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200291 +; + +-- Apr 21, 2021, 5:37:46 PM CEST +UPDATE AD_Process_Para SET DefaultValue='Y',Updated=TO_TIMESTAMP('2021-04-21 17:37:46','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_Para_ID=200292 +; + +-- Apr 21, 2021, 5:39:08 PM CEST +INSERT INTO AD_Element (AD_Element_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,ColumnName,Name,Description,Help,PrintName,EntityType,AD_Element_UU) VALUES (203483,0,0,'Y',TO_TIMESTAMP('2021-04-21 17:38:43','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-04-21 17:38:43','YYYY-MM-DD HH24:MI:SS'),100,'IsMigrateData','Migrate Data',NULL,NULL,'Migrate Data','D','cc8e6b76-fd73-4309-8fc6-2d9ead66d39d') +; + +-- Apr 21, 2021, 5:39:16 PM CEST +INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,DefaultValue,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted,IsAutocomplete) VALUES (200340,0,0,'Y',TO_TIMESTAMP('2021-04-21 17:39:15','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-04-21 17:39:15','YYYY-MM-DD HH24:MI:SS'),100,'Migrate Data',200117,70,20,'N',1,'Y','Y','IsMigrateData','Y','D',203483,'c060a763-cdf5-4b44-9486-5be5fb523674','N','N') +; + +-- Apr 21, 2021, 5:42:35 PM CEST +INSERT INTO AD_Process_Para (AD_Process_Para_ID,AD_Client_ID,AD_Org_ID,IsActive,Created,CreatedBy,Updated,UpdatedBy,Name,Description,Help,AD_Process_ID,SeqNo,AD_Reference_ID,IsRange,FieldLength,IsMandatory,ColumnName,IsCentrallyMaintained,EntityType,AD_Element_ID,AD_Process_Para_UU,IsEncrypted,MandatoryLogic,IsAutocomplete) VALUES (200341,0,0,'Y',TO_TIMESTAMP('2021-04-21 17:42:35','YYYY-MM-DD HH24:MI:SS'),100,TO_TIMESTAMP('2021-04-21 17:42:35','YYYY-MM-DD HH24:MI:SS'),100,'Record ID','Direct internal record ID','The Record ID is the internal unique identifier of a record. Please note that zooming to the record may not be successful for Orders, Invoices and Shipment/Receipts as sometimes the Sales Order type is not known.',200117,80,11,'Y',22,'N','Record_ID','Y','D',538,'c65e1cd9-1c1b-450c-a789-58feb9b7afe0','N',NULL,'N') +; + +-- Apr 21, 2021, 5:54:28 PM CEST +UPDATE AD_Process SET Help='

WARNING: This process can be destructive, so please be sure that you have a backup of the database, as well as a backup of your old storage provider.

+ +

The process migrates files between storage providers.

+ + + +

In case of failure or timeout, the process can be launched again, it commits on every file migrated.

',Updated=TO_TIMESTAMP('2021-04-21 17:54:28','YYYY-MM-DD HH24:MI:SS'),UpdatedBy=100 WHERE AD_Process_ID=200117 +; + +-- set providers with actual values from client +UPDATE ad_attachment a SET ad_storageprovider_id = (SELECT ci.ad_storageprovider_id FROM ad_clientinfo ci WHERE ci.ad_client_id=a.ad_client_id) +WHERE a.ad_client_id IN (SELECT ad_client_id FROM ad_clientinfo WHERE ad_storageprovider_id IS NOT NULL); + +UPDATE ad_image i SET ad_storageprovider_id = (SELECT ci.storageimage_id FROM ad_clientinfo ci WHERE ci.ad_client_id=i.ad_client_id) +WHERE ad_client_id IN (SELECT ad_client_id FROM ad_clientinfo WHERE storageimage_id IS NOT NULL); + +UPDATE ad_archive a SET ad_storageprovider_id = (SELECT ci.storagearchive_id FROM ad_clientinfo ci WHERE ci.ad_client_id=a.ad_client_id) +WHERE ad_client_id IN (SELECT ad_client_id FROM ad_clientinfo WHERE storagearchive_id IS NOT NULL); + +SELECT register_migration_script('202104162211_IDEMPIERE-4762.sql') FROM dual +; + diff --git a/org.adempiere.base.process/src/org/idempiere/process/MigrateStorageProvider.java b/org.adempiere.base.process/src/org/idempiere/process/MigrateStorageProvider.java index 9633a927d6..813d1db697 100644 --- a/org.adempiere.base.process/src/org/idempiere/process/MigrateStorageProvider.java +++ b/org.adempiere.base.process/src/org/idempiere/process/MigrateStorageProvider.java @@ -1,4 +1,4 @@ -/********************************************************************** +/*********************************************************************** * This file is part of iDempiere ERP Open Source * * http://www.idempiere.org * * * @@ -28,8 +28,6 @@ package org.idempiere.process; import java.sql.SQLException; import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.List; import java.util.logging.Level; import org.compiere.model.IArchiveStore; @@ -57,6 +55,9 @@ public class MigrateStorageProvider extends SvrProcess { private boolean p_IsMigrateAttachment = false; private boolean p_IsMigrateArchive = false; private boolean p_IsMigrateImage = false; + private boolean p_IsMigrateData = true; + private int p_IDFrom = 0; + private int p_IDTo = 0; private boolean p_DeleteOld = false; int cntAttachment = 0; int cntArchive = 0; @@ -82,6 +83,11 @@ public class MigrateStorageProvider extends SvrProcess { p_IsMigrateArchive = para.getParameterAsBoolean(); } else if ("IsMigrateImage".equals(name)) { p_IsMigrateImage = para.getParameterAsBoolean(); + } else if ("IsMigrateData".equals(name)) { + p_IsMigrateData = para.getParameterAsBoolean(); + } else if ("Record_ID".equals(name)) { + p_IDFrom = para.getParameterAsInt(); + p_IDTo = para.getParameter_ToAsInt(); } else if ("DeleteOld".equals(name)) { p_DeleteOld = para.getParameterAsBoolean(); } else { @@ -103,18 +109,23 @@ public class MigrateStorageProvider extends SvrProcess { + ", IsMigrateAttachment=" + p_IsMigrateAttachment + ", IsMigrateArchive=" + p_IsMigrateArchive + ", IsMigrateImage=" + p_IsMigrateImage + + ", IsMigrateData=" + p_IsMigrateData + + ", IDFrom=" + p_IDFrom + + ", IDTo=" + p_IDTo + ", DeleteOld=" + p_DeleteOld); if ( ! (p_IsMigrateAttachment || p_IsMigrateArchive || p_IsMigrateImage ) ) { return "Nothing to migrate, please select an option"; } + MStorageProvider newProvider = MStorageProvider.get(getCtx(), p_AD_StorageProvider_ID); + // Create list of clients to process: // - single AD_Client // - clients using the actual storage provider (depending on the isMigrate flags) - List clients = new ArrayList(); + int[] clientsToUpdate; if (p_AD_Client_ID >= 0) { - clients.add(p_AD_Client_ID); + clientsToUpdate = new int[] {p_AD_Client_ID}; p_Actual_StorageProvider_ID = 0; } else { StringBuilder whereClause = new StringBuilder(); @@ -139,71 +150,90 @@ public class MigrateStorageProvider extends SvrProcess { } whereClause.append("StorageImage_ID").append(storageClause); } - int[] ids = new Query(getCtx(), MClientInfo.Table_Name, whereClause.toString(), get_TrxName()) + clientsToUpdate = new Query(getCtx(), MClientInfo.Table_Name, whereClause.toString(), get_TrxName()) .setOrderBy("AD_Client_ID") .getIDs(); - for (int id : ids) { - clients.add(id); - } } - if ( clients.size() == 0) { - return "Nothing to migrate, no clients with that storage provider"; - } - MStorageProvider newProvider = new MStorageProvider(getCtx(), p_AD_StorageProvider_ID, get_TrxName()); - boolean isNewStorageDB = MStorageProvider.METHOD_Database.equals(newProvider.getMethod()); - int idxClient = 0; - int totalClients = clients.size(); - // for each client - for (int clientid : clients) { - idxClient++; + // Start the process updating the provider, data migration goes later + for (int clientid : clientsToUpdate) { MClientInfo clientInfo = MClientInfo.getCopy(getCtx(), clientid, (String)null); MClient client = MClient.get(getCtx(), clientid); - int odometer = 10; - if (p_IsMigrateAttachment) { - if ( clientInfo.getAD_StorageProvider_ID() == p_AD_StorageProvider_ID - || (clientInfo.getAD_StorageProvider_ID() == 0 && isNewStorageDB)) { - String msg = client.getName() + " has already attachment storage " + newProvider.getName(); - addLog(msg); - } else { - migrateAttachments(newProvider, idxClient, totalClients, clientid, clientInfo, client, odometer); - } + if ( p_IsMigrateAttachment + && clientInfo.getAD_StorageProvider_ID() != p_AD_StorageProvider_ID) { + clientInfo.setAD_StorageProvider_ID(p_AD_StorageProvider_ID); + clientInfo.saveEx(); + String msg = "Attachment provider set to " + newProvider.getName() + " on " + client.getName(); + addLog(msg); } - if (p_IsMigrateArchive) { - if ( clientInfo.getStorageArchive_ID() == p_AD_StorageProvider_ID - || (clientInfo.getStorageArchive_ID() == 0 && isNewStorageDB)) { - String msg = client.getName() + " has already archive storage " + newProvider.getName(); - addLog(msg); - } else { - migrateArchives(newProvider, idxClient, totalClients, clientid, clientInfo, client, odometer); - } + if ( p_IsMigrateArchive + && clientInfo.getStorageArchive_ID() != p_AD_StorageProvider_ID) { + clientInfo.setStorageArchive_ID(p_AD_StorageProvider_ID); + clientInfo.saveEx(); + String msg = "Archive provider set to " + newProvider.getName() + " on " + client.getName(); + addLog(msg); } - if (p_IsMigrateImage) { - if ( clientInfo.getStorageImage_ID() == p_AD_StorageProvider_ID - || (clientInfo.getStorageImage_ID() == 0 && isNewStorageDB)) { - String msg = client.getName() + " has already image storage " + newProvider.getName(); - addLog(msg); - } else { - migrateImages(newProvider, idxClient, totalClients, clientid, clientInfo, client, odometer); - } + if ( p_IsMigrateImage + && clientInfo.getStorageImage_ID() != p_AD_StorageProvider_ID) { + clientInfo.setStorageImage_ID(p_AD_StorageProvider_ID); + clientInfo.saveEx(); + String msg = "Image provider set to " + newProvider.getName() + " on " + client.getName(); + addLog(msg); + } + } + commitEx(); + CacheMgt.get().reset(MClientInfo.Table_Name); + + if (p_IsMigrateData) { + int[] clientsToMigrate; + if (p_AD_Client_ID >= 0) { + clientsToMigrate = new int[] {p_AD_Client_ID}; + } else { + final String whereMigrate = "(AD_StorageProvider_ID=? OR StorageArchive_ID=? OR StorageImage_ID=?)"; + clientsToMigrate = new Query(getCtx(), MClientInfo.Table_Name, whereMigrate, get_TrxName()) + .setOrderBy("AD_Client_ID") + .setParameters(p_AD_StorageProvider_ID, p_AD_StorageProvider_ID, p_AD_StorageProvider_ID) + .getIDs(); } - } // end for each client + int idxClient = 0; + int totalClients = clientsToMigrate.length; + + // for each client + for (int clientid : clientsToMigrate) { + idxClient++; + MClient client = MClient.get(getCtx(), clientid); + int odometer = 10; + + if (p_IsMigrateAttachment) { + migrateAttachments(newProvider, idxClient, totalClients, clientid, client, odometer); + } + + if (p_IsMigrateArchive) { + migrateArchives(newProvider, idxClient, totalClients, clientid, client, odometer); + } + + if (p_IsMigrateImage) { + migrateImages(newProvider, idxClient, totalClients, clientid, client, odometer); + } + } // end for each client + + } return "@Updated@ " + cntAttachment + " @AD_Attachment_ID@, " + cntArchive + " @AD_Archive_ID@, " + cntImage + " @AD_Image_ID@"; } // doIt private void migrateAttachments(MStorageProvider newProvider, int idxClient, int totalClients, int clientid, - MClientInfo clientInfo, MClient client, int odometer) throws SQLException { + MClient client, int odometer) throws SQLException { // migrate attachment status(idxClient, totalClients, "Migrating attachments for " + client.getName()); - int[] attachIds = new Query(getCtx(), MAttachment.Table_Name, "AD_Client_ID=?", get_TrxName()) - .setParameters(clientid) + final String where = "AD_Client_ID=? AND (?=0 OR AD_Attachment_ID>=?) AND (?=0 OR AD_Attachment_ID<=?) AND COALESCE(AD_StorageProvider_ID,0)!=?"; + int[] attachIds = new Query(getCtx(), MAttachment.Table_Name, where, get_TrxName()) + .setParameters(clientid, p_IDFrom, p_IDFrom, p_IDTo, p_IDTo, p_AD_StorageProvider_ID) .setOrderBy("AD_Attachment_ID") - .setForUpdate(true) // lock these records in the table .getIDs(); int cntRecords = attachIds.length; // iterate on each record of the associated table @@ -214,55 +244,38 @@ public class MigrateStorageProvider extends SvrProcess { progress(idxClient, totalClients, idxAttach, cntRecords, "Migrating attachment "); } MAttachment attachment = new MAttachment(getCtx(), attachId, get_TrxName()); + int oldProviderId = attachment.getAD_StorageProvider_ID(); attachment.getEntries(); attachment.setStorageProvider(newProvider); attachment.set_ValueNoCheck("Updated", new Timestamp(System.currentTimeMillis())); // to force save // create file on the new storage provider attachment.saveEx(); cntAttachment++; - } - // set the corresponding storage provider - int oldProviderId = clientInfo.getAD_StorageProvider_ID(); - clientInfo.setAD_StorageProvider_ID(p_AD_StorageProvider_ID); - clientInfo.saveEx(); - // cache reset - CacheMgt.get().reset(MClientInfo.Table_Name, clientInfo.getAD_Client_ID()); - commitEx(); - String msg = "Migrated " + cntRecords + " attachments on " + client.getName(); - addLog(msg); - // if delete old - if (p_DeleteOld) { - MStorageProvider oldProvider = new MStorageProvider(getCtx(), oldProviderId, get_TrxName()); - if (! (oldProviderId == 0 || MStorageProvider.METHOD_Database.equals(oldProvider.getMethod()))) { - // DB method doesn't require delete - IAttachmentStore oldStore = oldProvider.getAttachmentStore(); - // iterate on each record of the associated table - idxAttach = 0; - for (int attachId : attachIds) { - idxAttach++; - if (idxAttach % odometer == 0) { - progress(idxClient, totalClients, idxAttach, cntRecords, "Deleting old attachment "); - } - // delete file on old storage - MAttachment attachment = new MAttachment(getCtx(), attachId, get_TrxName()); - attachment.setStorageProvider(newProvider); - attachment.getEntries(); + // commit on every record migrated + commitEx(); + + if (p_DeleteOld) { + MStorageProvider oldProvider = MStorageProvider.get(getCtx(), oldProviderId); + if (! (oldProviderId == 0 || MStorageProvider.METHOD_Database.equals(oldProvider.getMethod()))) { // DB method doesn't require delete + IAttachmentStore oldStore = oldProvider.getAttachmentStore(); + // delete file on old storage oldStore.delete(attachment, oldProvider); + commitEx(); } - msg = "Deleted " + cntRecords + " old attachment files on " + client.getName(); - addLog(msg); } } + String msg = "Migrated " + cntRecords + " attachments on " + client.getName(); + addLog(msg); } private void migrateArchives(MStorageProvider newProvider, int idxClient, int totalClients, int clientid, - MClientInfo clientInfo, MClient client, int odometer) throws SQLException { + MClient client, int odometer) throws SQLException { // migrate archive status(idxClient, totalClients, "Migrating archives for " + client.getName()); - int[] archiveIds = new Query(getCtx(), MArchive.Table_Name, "AD_Client_ID=?", get_TrxName()) - .setParameters(clientid) + final String where = "AD_Client_ID=? AND (?=0 OR AD_Archive_ID>=?) AND (?=0 OR AD_Archive_ID<=?) AND COALESCE(AD_StorageProvider_ID,0)!=?"; + int[] archiveIds = new Query(getCtx(), MArchive.Table_Name, where, get_TrxName()) + .setParameters(clientid, p_IDFrom, p_IDFrom, p_IDTo, p_IDTo, p_AD_StorageProvider_ID) .setOrderBy("AD_Archive_ID") - .setForUpdate(true) // lock these records in the table .getIDs(); int cntRecords = archiveIds.length; // iterate on each record of the associated table @@ -273,6 +286,7 @@ public class MigrateStorageProvider extends SvrProcess { progress(idxClient, totalClients, idxArchive, cntRecords, "Migrating archive "); } MArchive archive = new MArchive(getCtx(), archiveId, get_TrxName()); + int oldProviderId = archive.getAD_StorageProvider_ID(); byte[] data = archive.getBinaryData(); archive.setStorageProvider(newProvider); archive.setBinaryData(data); @@ -280,48 +294,31 @@ public class MigrateStorageProvider extends SvrProcess { // create file on the new storage provider archive.saveEx(); cntArchive++; - } - // set the corresponding storage provider - int oldProviderId = clientInfo.getStorageArchive_ID(); - clientInfo.setStorageArchive_ID(p_AD_StorageProvider_ID); - clientInfo.saveEx(); - // cache reset - CacheMgt.get().reset(MClientInfo.Table_Name, clientInfo.getAD_Client_ID()); - commitEx(); - String msg = "Migrated " + cntRecords + " archives on " + client.getName(); - addLog(msg); - // if delete old - if (p_DeleteOld) { - MStorageProvider oldProvider = new MStorageProvider(getCtx(), oldProviderId, get_TrxName()); - if (! (oldProviderId == 0 || MStorageProvider.METHOD_Database.equals(oldProvider.getMethod()))) { - // DB method doesn't require delete - IArchiveStore oldStore = oldProvider.getArchiveStore(); - // iterate on each record of the associated table - idxArchive = 0; - for (int archiveId : archiveIds) { - idxArchive++; - if (idxArchive % odometer == 0) { - progress(idxClient, totalClients, idxArchive, cntRecords, "Deleting old archive "); - } - // delete file on old storage - MArchive archive = new MArchive(getCtx(), archiveId, get_TrxName()); - archive.setStorageProvider(newProvider); + // commit on every record migrated + commitEx(); + + if (p_DeleteOld) { + MStorageProvider oldProvider = MStorageProvider.get(getCtx(), oldProviderId); + if (! (oldProviderId == 0 || MStorageProvider.METHOD_Database.equals(oldProvider.getMethod()))) { // DB method doesn't require delete + IArchiveStore oldStore = oldProvider.getArchiveStore(); + // delete file on old storage oldStore.deleteArchive(archive, oldProvider); + commitEx(); } - msg = "Deleted " + cntRecords + " old archive files on " + client.getName(); - addLog(msg); } } + String msg = "Migrated " + cntRecords + " archives on " + client.getName(); + addLog(msg); } private void migrateImages(MStorageProvider newProvider, int idxClient, int totalClients, int clientid, - MClientInfo clientInfo, MClient client, int odometer) throws SQLException { + MClient client, int odometer) throws SQLException { // migrate image status(idxClient, totalClients, "Migrating images for " + client.getName()); - int[] imageIds = new Query(getCtx(), MImage.Table_Name, "AD_Client_ID=?", get_TrxName()) - .setParameters(clientid) + final String where = "AD_Client_ID=? AND (?=0 OR AD_Image_ID>=?) AND (?=0 OR AD_Image_ID<=?) AND COALESCE(AD_StorageProvider_ID,0)!=?"; + int[] imageIds = new Query(getCtx(), MImage.Table_Name, where, get_TrxName()) + .setParameters(clientid, p_IDFrom, p_IDFrom, p_IDTo, p_IDTo, p_AD_StorageProvider_ID) .setOrderBy("AD_Image_ID") - .setForUpdate(true) // lock these records in the table .getIDs(); int cntRecords = imageIds.length; // iterate on each record of the associated table @@ -332,45 +329,28 @@ public class MigrateStorageProvider extends SvrProcess { progress(idxClient, totalClients, idxImage, cntRecords, "Migrating image "); } MImage image = new MImage(getCtx(), imageId, get_TrxName()); + int oldProviderId = image.getAD_StorageProvider_ID(); byte[] data = image.getBinaryData(); image.setStorageProvider(newProvider); image.setBinaryData(data); image.set_ValueNoCheck("Updated", new Timestamp(System.currentTimeMillis())); // to force save // create file on the new storage provider image.saveEx(); - cntImage++; - } - // set the corresponding storage provider - int oldProviderId = clientInfo.getStorageImage_ID(); - clientInfo.setStorageImage_ID(p_AD_StorageProvider_ID); - clientInfo.saveEx(); - // cache reset - CacheMgt.get().reset(MClientInfo.Table_Name, clientInfo.getAD_Client_ID()); - commitEx(); - String msg = "Migrated " + cntRecords + " images on " + client.getName(); - addLog(msg); - // if delete old - if (p_DeleteOld) { - MStorageProvider oldProvider = new MStorageProvider(getCtx(), oldProviderId, get_TrxName()); - if (! (oldProviderId == 0 || MStorageProvider.METHOD_Database.equals(oldProvider.getMethod()))) { - // DB method doesn't require delete - IImageStore oldStore = oldProvider.getImageStore(); - // iterate on each record of the associated table - idxImage = 0; - for (int imageId : imageIds) { - idxImage++; - if (idxImage % odometer == 0) { - progress(idxClient, totalClients, idxImage, cntRecords, "Deleting old image "); - } - // delete file on old storage - MImage image = new MImage(getCtx(), imageId, get_TrxName()); - image.setStorageProvider(newProvider); + // commit on every record migrated + commitEx(); + + if (p_DeleteOld) { + MStorageProvider oldProvider = MStorageProvider.get(getCtx(), oldProviderId); + if (! (oldProviderId == 0 || MStorageProvider.METHOD_Database.equals(oldProvider.getMethod()))) { // DB method doesn't require delete + IImageStore oldStore = oldProvider.getImageStore(); + // delete file on old storage oldStore.delete(image, oldProvider); + commitEx(); } - msg = "Deleted " + cntRecords + " old image files on " + client.getName(); - addLog(msg); } } + String msg = "Migrated " + cntRecords + " images on " + client.getName(); + addLog(msg); } private void progress(int idxClient, int totalClients, int idxRecord, int cntRecords, String msg) { diff --git a/org.adempiere.base/src/org/compiere/model/AttachmentFileSystem.java b/org.adempiere.base/src/org/compiere/model/AttachmentFileSystem.java index 9990ae04f5..de6c5df870 100644 --- a/org.adempiere.base/src/org/compiere/model/AttachmentFileSystem.java +++ b/org.adempiere.base/src/org/compiere/model/AttachmentFileSystem.java @@ -48,7 +48,9 @@ import org.xml.sax.SAXException; * */ public class AttachmentFileSystem implements IAttachmentStore { - + + // TODO: Implement FileSystemFallbackDB + private final CLogger log = CLogger.getCLogger(getClass()); @Override diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_Archive.java b/org.adempiere.base/src/org/compiere/model/I_AD_Archive.java index 0ca9879398..5dd69755a4 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_Archive.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_Archive.java @@ -99,6 +99,17 @@ public interface I_AD_Archive public org.compiere.model.I_AD_Process getAD_Process() throws RuntimeException; + /** Column name AD_StorageProvider_ID */ + public static final String COLUMNNAME_AD_StorageProvider_ID = "AD_StorageProvider_ID"; + + /** Set Storage Provider */ + public void setAD_StorageProvider_ID (int AD_StorageProvider_ID); + + /** Get Storage Provider */ + public int getAD_StorageProvider_ID(); + + public org.compiere.model.I_AD_StorageProvider getAD_StorageProvider() throws RuntimeException; + /** Column name AD_Table_ID */ public static final String COLUMNNAME_AD_Table_ID = "AD_Table_ID"; diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_Attachment.java b/org.adempiere.base/src/org/compiere/model/I_AD_Attachment.java index 25166edb4f..ae7a7fbee8 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_Attachment.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_Attachment.java @@ -84,6 +84,17 @@ public interface I_AD_Attachment */ public int getAD_Org_ID(); + /** Column name AD_StorageProvider_ID */ + public static final String COLUMNNAME_AD_StorageProvider_ID = "AD_StorageProvider_ID"; + + /** Set Storage Provider */ + public void setAD_StorageProvider_ID (int AD_StorageProvider_ID); + + /** Get Storage Provider */ + public int getAD_StorageProvider_ID(); + + public org.compiere.model.I_AD_StorageProvider getAD_StorageProvider() throws RuntimeException; + /** Column name AD_Table_ID */ public static final String COLUMNNAME_AD_Table_ID = "AD_Table_ID"; diff --git a/org.adempiere.base/src/org/compiere/model/I_AD_Image.java b/org.adempiere.base/src/org/compiere/model/I_AD_Image.java index 340ebc2ab6..b2e38dee70 100644 --- a/org.adempiere.base/src/org/compiere/model/I_AD_Image.java +++ b/org.adempiere.base/src/org/compiere/model/I_AD_Image.java @@ -84,6 +84,17 @@ public interface I_AD_Image */ public int getAD_Org_ID(); + /** Column name AD_StorageProvider_ID */ + public static final String COLUMNNAME_AD_StorageProvider_ID = "AD_StorageProvider_ID"; + + /** Set Storage Provider */ + public void setAD_StorageProvider_ID (int AD_StorageProvider_ID); + + /** Get Storage Provider */ + public int getAD_StorageProvider_ID(); + + public org.compiere.model.I_AD_StorageProvider getAD_StorageProvider() throws RuntimeException; + /** Column name BinaryData */ public static final String COLUMNNAME_BinaryData = "BinaryData"; diff --git a/org.adempiere.base/src/org/compiere/model/MArchive.java b/org.adempiere.base/src/org/compiere/model/MArchive.java index f31c86a4cb..855943b73b 100644 --- a/org.adempiere.base/src/org/compiere/model/MArchive.java +++ b/org.adempiere.base/src/org/compiere/model/MArchive.java @@ -153,8 +153,12 @@ public class MArchive extends X_AD_Archive { * @param trxName */ private void initArchiveStoreDetails(Properties ctx, String trxName) { - MClientInfo clientInfo = MClientInfo.get(ctx, getAD_Client_ID()); - provider=new MStorageProvider(ctx, clientInfo.getStorageArchive_ID(), trxName); + if (is_new()) { + MClientInfo clientInfo = MClientInfo.get(ctx, getAD_Client_ID()); + setStorageProvider(MStorageProvider.get(ctx, clientInfo.getStorageArchive_ID())); + } else { + setStorageProvider(MStorageProvider.get(ctx, getAD_StorageProvider_ID())); + } } /** @@ -302,6 +306,7 @@ public class MArchive extends X_AD_Archive { */ public void setStorageProvider(MStorageProvider p) { provider = p; + setAD_StorageProvider_ID(p.getAD_StorageProvider_ID()); } /** diff --git a/org.adempiere.base/src/org/compiere/model/MAttachment.java b/org.adempiere.base/src/org/compiere/model/MAttachment.java index ace7e5b395..899ed74147 100644 --- a/org.adempiere.base/src/org/compiere/model/MAttachment.java +++ b/org.adempiere.base/src/org/compiere/model/MAttachment.java @@ -169,8 +169,12 @@ public class MAttachment extends X_AD_Attachment */ private void initAttachmentStoreDetails(Properties ctx, String trxName) { - MClientInfo clientInfo = MClientInfo.get(ctx, getAD_Client_ID()); - provider=new MStorageProvider(ctx, clientInfo.getAD_StorageProvider_ID(), trxName); + if (is_new()) { + MClientInfo clientInfo = MClientInfo.get(ctx, getAD_Client_ID()); + setStorageProvider(MStorageProvider.get(ctx, clientInfo.getAD_StorageProvider_ID())); + } else { + setStorageProvider(MStorageProvider.get(ctx, getAD_StorageProvider_ID())); + } } /** @@ -705,6 +709,7 @@ public class MAttachment extends X_AD_Attachment */ public void setStorageProvider(MStorageProvider p) { provider = p; + setAD_StorageProvider_ID(p.getAD_StorageProvider_ID()); } } // MAttachment diff --git a/org.adempiere.base/src/org/compiere/model/MImage.java b/org.adempiere.base/src/org/compiere/model/MImage.java index 519ac24a91..7d0a9d6564 100644 --- a/org.adempiere.base/src/org/compiere/model/MImage.java +++ b/org.adempiere.base/src/org/compiere/model/MImage.java @@ -97,8 +97,11 @@ public class MImage extends X_AD_Image implements ImmutablePOSupport public static MImage getCopy(Properties ctx, int AD_Image_ID, String trxName) { MImage img = get(AD_Image_ID); - if (img != null && img.getAD_Image_ID() > 0) + if (img != null && img.getAD_Image_ID() > 0) { + MStorageProvider copyprov = img.provider; img = new MImage(ctx, img, trxName); + img.setStorageProvider(copyprov); + } return img; } @@ -399,8 +402,12 @@ public class MImage extends X_AD_Image implements ImmutablePOSupport * @param trxName */ private void initImageStoreDetails(Properties ctx, String trxName) { - MClientInfo clientInfo = MClientInfo.get(ctx, getAD_Client_ID()); - provider=new MStorageProvider(ctx, clientInfo.getStorageImage_ID(), trxName); + if (is_new()) { + MClientInfo clientInfo = MClientInfo.get(ctx, getAD_Client_ID()); + setStorageProvider(MStorageProvider.get(ctx, clientInfo.getStorageImage_ID())); + } else { + setStorageProvider(MStorageProvider.get(ctx, getAD_StorageProvider_ID())); + } } /** @@ -410,6 +417,7 @@ public class MImage extends X_AD_Image implements ImmutablePOSupport */ public void setStorageProvider(MStorageProvider p) { provider = p; + setAD_StorageProvider_ID(p.getAD_StorageProvider_ID()); } public byte[] getByteData(){ diff --git a/org.adempiere.base/src/org/compiere/model/MStorageProvider.java b/org.adempiere.base/src/org/compiere/model/MStorageProvider.java index 08ca0772de..a02631a85e 100644 --- a/org.adempiere.base/src/org/compiere/model/MStorageProvider.java +++ b/org.adempiere.base/src/org/compiere/model/MStorageProvider.java @@ -25,13 +25,67 @@ import org.adempiere.base.ServiceQuery; import org.adempiere.exceptions.AdempiereException; import org.compiere.util.CCache; import org.compiere.util.DB; +import org.compiere.util.Env; +import org.idempiere.cache.ImmutableIntPOCache; +import org.idempiere.cache.ImmutablePOSupport; -public class MStorageProvider extends X_AD_StorageProvider { +public class MStorageProvider extends X_AD_StorageProvider implements ImmutablePOSupport { /** * */ - private static final long serialVersionUID = 6030898744999167572L; + private static final long serialVersionUID = -7444967391781941193L; + /** Cache */ + static private ImmutableIntPOCache s_cache = new ImmutableIntPOCache(Table_Name, 10); + + /** + * Get Storage Provider (cached) (immutable) + * @param AD_StorageProvider_ID id + * @return Storage Provider + */ + public static MStorageProvider get (int AD_StorageProvider_ID) + { + return get(Env.getCtx(), AD_StorageProvider_ID); + } + + /** + * Get Storage Provider (cached) (immutable) + * @param ctx context + * @param AD_StorageProvider_ID id + * @return Storage Provider + */ + public static MStorageProvider get (Properties ctx, int AD_StorageProvider_ID) + { + Integer key = Integer.valueOf(AD_StorageProvider_ID); + MStorageProvider retValue = s_cache.get(ctx, key, e -> new MStorageProvider(ctx, e)); + if (retValue == null) + { + retValue = new MStorageProvider (ctx, AD_StorageProvider_ID, null); + if (retValue.get_ID() == AD_StorageProvider_ID) + { + s_cache.put(key, retValue, e -> new MStorageProvider(Env.getCtx(), e)); + return retValue; + } + return null; + } + return retValue; + } // get + + /** + * Get updateable copy of MStorageProvider from cache + * @param ctx + * @param AD_StorageProvider_ID + * @param trxName + * @return MStorageProvider + */ + public static MStorageProvider getCopy(Properties ctx, int AD_StorageProvider_ID, String trxName) + { + MStorageProvider rt = get(AD_StorageProvider_ID); + if (rt != null) + rt = new MStorageProvider(ctx, rt, trxName); + return rt; + } + public MStorageProvider(Properties ctx, int AD_StorageProvider_ID, String trxName) { super(ctx, AD_StorageProvider_ID, trxName); } @@ -40,6 +94,37 @@ public class MStorageProvider extends X_AD_StorageProvider { super(ctx, rs, trxName); } + /** + * + * @param copy + */ + public MStorageProvider(MStorageProvider copy) + { + this(Env.getCtx(), copy); + } + + /** + * + * @param ctx + * @param copy + */ + public MStorageProvider(Properties ctx, MStorageProvider copy) + { + this(ctx, copy, (String) null); + } + + /** + * + * @param ctx + * @param copy + * @param trxName + */ + public MStorageProvider(Properties ctx, MStorageProvider copy, String trxName) + { + this(ctx, 0, trxName); + copyPO(copy); + } + /** * * @return {@link IAttachmentStore} @@ -174,4 +259,13 @@ public class MStorageProvider extends X_AD_StorageProvider { return DB.getSQLValueEx(null, sql); } + @Override + public MStorageProvider markImmutable() { + if (is_Immutable()) + return this; + + makeImmutable(); + return this; + } + } diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_Archive.java b/org.adempiere.base/src/org/compiere/model/X_AD_Archive.java index 91b31678e2..6fac9c6e93 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_Archive.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_Archive.java @@ -30,7 +30,7 @@ public class X_AD_Archive extends PO implements I_AD_Archive, I_Persistent /** * */ - private static final long serialVersionUID = 20201220L; + private static final long serialVersionUID = 20210416L; /** Standard Constructor */ public X_AD_Archive (Properties ctx, int AD_Archive_ID, String trxName) @@ -138,6 +138,31 @@ public class X_AD_Archive extends PO implements I_AD_Archive, I_Persistent return ii.intValue(); } + public org.compiere.model.I_AD_StorageProvider getAD_StorageProvider() throws RuntimeException + { + return (org.compiere.model.I_AD_StorageProvider)MTable.get(getCtx(), org.compiere.model.I_AD_StorageProvider.Table_Name) + .getPO(getAD_StorageProvider_ID(), get_TrxName()); } + + /** Set Storage Provider. + @param AD_StorageProvider_ID Storage Provider */ + public void setAD_StorageProvider_ID (int AD_StorageProvider_ID) + { + if (AD_StorageProvider_ID < 1) + set_ValueNoCheck (COLUMNNAME_AD_StorageProvider_ID, null); + else + set_ValueNoCheck (COLUMNNAME_AD_StorageProvider_ID, Integer.valueOf(AD_StorageProvider_ID)); + } + + /** Get Storage Provider. + @return Storage Provider */ + public int getAD_StorageProvider_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_AD_StorageProvider_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + public org.compiere.model.I_AD_Table getAD_Table() throws RuntimeException { return (org.compiere.model.I_AD_Table)MTable.get(getCtx(), org.compiere.model.I_AD_Table.Table_Name) diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_Attachment.java b/org.adempiere.base/src/org/compiere/model/X_AD_Attachment.java index 759df9fbd1..bd998f6111 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_Attachment.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_Attachment.java @@ -30,7 +30,7 @@ public class X_AD_Attachment extends PO implements I_AD_Attachment, I_Persistent /** * */ - private static final long serialVersionUID = 20201220L; + private static final long serialVersionUID = 20210416L; /** Standard Constructor */ public X_AD_Attachment (Properties ctx, int AD_Attachment_ID, String trxName) @@ -110,6 +110,31 @@ public class X_AD_Attachment extends PO implements I_AD_Attachment, I_Persistent return (String)get_Value(COLUMNNAME_AD_Attachment_UU); } + public org.compiere.model.I_AD_StorageProvider getAD_StorageProvider() throws RuntimeException + { + return (org.compiere.model.I_AD_StorageProvider)MTable.get(getCtx(), org.compiere.model.I_AD_StorageProvider.Table_Name) + .getPO(getAD_StorageProvider_ID(), get_TrxName()); } + + /** Set Storage Provider. + @param AD_StorageProvider_ID Storage Provider */ + public void setAD_StorageProvider_ID (int AD_StorageProvider_ID) + { + if (AD_StorageProvider_ID < 1) + set_ValueNoCheck (COLUMNNAME_AD_StorageProvider_ID, null); + else + set_ValueNoCheck (COLUMNNAME_AD_StorageProvider_ID, Integer.valueOf(AD_StorageProvider_ID)); + } + + /** Get Storage Provider. + @return Storage Provider */ + public int getAD_StorageProvider_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_AD_StorageProvider_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + public org.compiere.model.I_AD_Table getAD_Table() throws RuntimeException { return (org.compiere.model.I_AD_Table)MTable.get(getCtx(), org.compiere.model.I_AD_Table.Table_Name) diff --git a/org.adempiere.base/src/org/compiere/model/X_AD_Image.java b/org.adempiere.base/src/org/compiere/model/X_AD_Image.java index d7df4c9c1e..35198992ed 100644 --- a/org.adempiere.base/src/org/compiere/model/X_AD_Image.java +++ b/org.adempiere.base/src/org/compiere/model/X_AD_Image.java @@ -30,7 +30,7 @@ public class X_AD_Image extends PO implements I_AD_Image, I_Persistent /** * */ - private static final long serialVersionUID = 20201220L; + private static final long serialVersionUID = 20210416L; /** Standard Constructor */ public X_AD_Image (Properties ctx, int AD_Image_ID, String trxName) @@ -110,6 +110,31 @@ public class X_AD_Image extends PO implements I_AD_Image, I_Persistent return (String)get_Value(COLUMNNAME_AD_Image_UU); } + public org.compiere.model.I_AD_StorageProvider getAD_StorageProvider() throws RuntimeException + { + return (org.compiere.model.I_AD_StorageProvider)MTable.get(getCtx(), org.compiere.model.I_AD_StorageProvider.Table_Name) + .getPO(getAD_StorageProvider_ID(), get_TrxName()); } + + /** Set Storage Provider. + @param AD_StorageProvider_ID Storage Provider */ + public void setAD_StorageProvider_ID (int AD_StorageProvider_ID) + { + if (AD_StorageProvider_ID < 1) + set_ValueNoCheck (COLUMNNAME_AD_StorageProvider_ID, null); + else + set_ValueNoCheck (COLUMNNAME_AD_StorageProvider_ID, Integer.valueOf(AD_StorageProvider_ID)); + } + + /** Get Storage Provider. + @return Storage Provider */ + public int getAD_StorageProvider_ID () + { + Integer ii = (Integer)get_Value(COLUMNNAME_AD_StorageProvider_ID); + if (ii == null) + return 0; + return ii.intValue(); + } + /** Set Binary Data. @param BinaryData Binary Data diff --git a/org.adempiere.pipo/src/org/adempiere/pipo2/PoExporter.java b/org.adempiere.pipo/src/org/adempiere/pipo2/PoExporter.java index 3669f17220..5f996dbbd8 100644 --- a/org.adempiere.pipo/src/org/adempiere/pipo2/PoExporter.java +++ b/org.adempiere.pipo/src/org/adempiere/pipo2/PoExporter.java @@ -305,7 +305,7 @@ public class PoExporter { if ("BinaryData".equals(columnName)) { MClientInfo ci = MClientInfo.get(po.getAD_Client_ID()); if (po.get_Table_ID() == MAttachment.Table_ID && ci.getAD_StorageProvider_ID() > 0) { - MStorageProvider sp = new MStorageProvider(po.getCtx(), ci.getAD_StorageProvider_ID(), po.get_TrxName()); + MStorageProvider sp = MStorageProvider.get(po.getCtx(), ci.getAD_StorageProvider_ID()); if (! MStorageProvider.METHOD_Database.equals(sp.getMethod())) { MAttachment att = new MAttachment(po.getCtx(), po.get_ID(), po.get_TrxName()); File tmpfile = att.saveAsZip(); @@ -316,13 +316,13 @@ public class PoExporter { } } } else if (po.get_Table_ID() == MImage.Table_ID && ci.getStorageImage_ID() > 0) { - MStorageProvider sp = new MStorageProvider(po.getCtx(), ci.getStorageImage_ID(), po.get_TrxName()); + MStorageProvider sp = MStorageProvider.get(po.getCtx(), ci.getStorageImage_ID()); if (! MStorageProvider.METHOD_Database.equals(sp.getMethod())) { MImage image = new MImage(po.getCtx(), po.get_ID(), po.get_TrxName()); value = image.getBinaryData(); } } else if (po.get_Table_ID() == MArchive.Table_ID && ci.getStorageArchive_ID() > 0) { - MStorageProvider sp = new MStorageProvider(po.getCtx(), ci.getStorageArchive_ID(), po.get_TrxName()); + MStorageProvider sp = MStorageProvider.get(po.getCtx(), ci.getStorageArchive_ID()); if (! MStorageProvider.METHOD_Database.equals(sp.getMethod())) { MArchive archive = new MArchive(po.getCtx(), po.get_ID(), po.get_TrxName()); File tmpfile = archive.saveAsZip();