Repository: lens Updated Branches: refs/heads/master a86cb883f -> cdac40874
LENS-1469: Support drop partition(s) for specific update periods Project: http://git-wip-us.apache.org/repos/asf/lens/repo Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/cdac4087 Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/cdac4087 Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/cdac4087 Branch: refs/heads/master Commit: cdac40874c09cb80dd17a70908c86c3ac5922ac7 Parents: a86cb88 Author: Amit Khanna <amitkhanna1...@gmail.com> Authored: Wed Oct 25 13:05:29 2017 +0530 Committer: Rajat Khandelwal <rajatgupt...@gmail.com> Committed: Wed Oct 25 13:05:29 2017 +0530 ---------------------------------------------------------------------- .../commands/LensDimensionTableCommands.java | 5 ++ .../lens/cli/commands/LensFactCommands.java | 15 +++- .../cli/commands/LogicalTableCrudCommand.java | 7 ++ .../apache/lens/cli/TestLensFactCommands.java | 2 +- .../java/org/apache/lens/client/LensClient.java | 4 + .../apache/lens/client/LensMetadataClient.java | 7 +- .../api/metastore/CubeMetastoreService.java | 3 + .../metastore/CubeMetastoreServiceImpl.java | 10 ++- .../server/metastore/MetastoreResource.java | 5 +- .../server/metastore/TestMetastoreService.java | 66 +++++++++++++- src/site/apt/user/cli.apt | 92 +++++++++++--------- 11 files changed, 160 insertions(+), 56 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java index 26650c1..f37a380 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java @@ -322,6 +322,11 @@ public class LensDimensionTableCommands extends LogicalTableCrudCommand<XDimensi } @Override + protected APIResult doDropPartitions(String tableName, String storageName, String filter, String updatePeriod) { + return getClient().dropAllPartitionsOfDim(tableName, storageName, filter); + } + + @Override protected APIResult doUpdatePartition(String tableName, String storageName, String validPath) { return getClient().updatePartitionOfDim(tableName, storageName, validPath); } http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java index a872998..63dd992 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java @@ -198,9 +198,10 @@ public class LensFactCommands extends LogicalTableCrudCommand<XFact> { /** * Drop all partitions of fact. * - * @param tableName fact name - * @param storageName storage name - * @param filter partition query filter + * @param tableName fact name + * @param storageName storage name + * @param filter partition query filter + * @param updatePeriod update period of partition to be dropped * @return the string */ @CliCommand(value = "fact drop partitions", @@ -209,8 +210,9 @@ public class LensFactCommands extends LogicalTableCrudCommand<XFact> { public String dropAllPartitionsOfFact( @CliOption(key = {"", "fact_name"}, mandatory = true, help = "<fact_name>") String tableName, @CliOption(key = {"", "storage_name"}, mandatory = true, help = "<storage_name>") String storageName, + @CliOption(key = {"", "update_period"}, mandatory = true, help = "<update_period>") String updatePeriod, @CliOption(key = {"", "filter"}, mandatory = false, help = "<partition-filter>") String filter) { - return dropPartitions(tableName, storageName, filter); + return dropPartitions(tableName, storageName, filter, updatePeriod); } /** @@ -327,6 +329,11 @@ public class LensFactCommands extends LogicalTableCrudCommand<XFact> { } @Override + protected APIResult doDropPartitions(String tableName, String storageName, String filter, String updatePeriod) { + return getClient().dropAllPartitionsOfFact(tableName, storageName, filter, updatePeriod); + } + + @Override protected APIResult doUpdatePartition(String tableName, String storageName, String validPath) { return getClient().updatePartitionOfFact(tableName, storageName, validPath); } http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java index e0b60c2..5b0c1d0 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java @@ -96,6 +96,10 @@ public abstract class LogicalTableCrudCommand<T> extends LensCRUDCommand<T> { return doDropPartitions(tableName, storageName, filter).toString().toLowerCase(); } + public String dropPartitions(String tableName, String storageName, String filter, String updatePeriod) { + return doDropPartitions(tableName, storageName, filter, updatePeriod).toString().toLowerCase(); + } + protected abstract List<String> getAll(String filter); public abstract List<String> getAllStorages(String name); @@ -116,6 +120,9 @@ public abstract class LogicalTableCrudCommand<T> extends LensCRUDCommand<T> { protected abstract APIResult doDropPartitions(String tableName, String storageName, String filter); + protected abstract APIResult doDropPartitions(String tableName, String storageName, String filter, + String updatePeriod); + protected abstract APIResult doUpdatePartition(String tableName, String storageName, String validPath); protected abstract APIResult doUpdatePartitions(String tableName, String storageName, String validPath); http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java index 927b439..67242d7 100644 --- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java +++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensFactCommands.java @@ -432,7 +432,7 @@ public class TestLensFactCommands extends LensCliApplicationTest { assertTrue(timelines.containsAll(command.getTimelines("fact1", FACT_LOCAL, "hourly", "dt"))); assertEquals(command.getTimelines("fact1", null, null, "dt"), timelines); assertEquals(command.getTimelines("fact1", FACT_LOCAL, null, "dt"), timelines); - String dropPartitionsStatus = command.dropAllPartitionsOfFact("fact1", FACT_LOCAL, null); + String dropPartitionsStatus = command.dropAllPartitionsOfFact("fact1", FACT_LOCAL, null, null); assertFalse(dropPartitionsStatus.contains("Syntax error, please try in following")); result = command.getAllPartitionsOfFact("fact1", FACT_LOCAL, filter); assertTrue(result.trim().isEmpty()); http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/lens-client/src/main/java/org/apache/lens/client/LensClient.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/LensClient.java b/lens-client/src/main/java/org/apache/lens/client/LensClient.java index 1de99fe..76c8cad 100644 --- a/lens-client/src/main/java/org/apache/lens/client/LensClient.java +++ b/lens-client/src/main/java/org/apache/lens/client/LensClient.java @@ -609,6 +609,10 @@ public class LensClient implements AutoCloseable { return mc.dropPartitionsOfFactTable(fact, storage, list); } + public APIResult dropAllPartitionsOfFact(String fact, String storage, String list, String updatePeriod) { + return mc.dropPartitionsOfFactTable(fact, storage, list, updatePeriod); + } + public APIResult dropAllPartitionsOfDim(String dim, String storage) { return mc.dropAllPartitionsOfDimensionTable(dim, storage); } http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/lens-client/src/main/java/org/apache/lens/client/LensMetadataClient.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/LensMetadataClient.java b/lens-client/src/main/java/org/apache/lens/client/LensMetadataClient.java index 8a05952..7b37769 100644 --- a/lens-client/src/main/java/org/apache/lens/client/LensMetadataClient.java +++ b/lens-client/src/main/java/org/apache/lens/client/LensMetadataClient.java @@ -602,16 +602,21 @@ public class LensMetadataClient { return getPartitionsOfFactTable(factName, storage, ""); } - public APIResult dropPartitionsOfFactTable(String factName, String storage, String filter) { + public APIResult dropPartitionsOfFactTable(String factName, String storage, String filter, String updatePeriod) { WebTarget target = getMetastoreWebTarget(); return translate(target.path("facts").path(factName) .path("storages").path(storage).path("partitions") .queryParam("sessionid", this.connection.getSessionHandle()) .queryParam("filter", filter) + .queryParam("updatePeriod", updatePeriod) .request(MediaType.APPLICATION_XML) .delete()); } + public APIResult dropPartitionsOfFactTable(String factName, String storage, String filter) { + return dropPartitionsOfFactTable(factName, storage, filter, null); + } + public APIResult dropPartitionsOfFactTable(String factName, String storage) { return dropPartitionsOfFactTable(factName, storage, ""); } http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/lens-server-api/src/main/java/org/apache/lens/server/api/metastore/CubeMetastoreService.java ---------------------------------------------------------------------- diff --git a/lens-server-api/src/main/java/org/apache/lens/server/api/metastore/CubeMetastoreService.java b/lens-server-api/src/main/java/org/apache/lens/server/api/metastore/CubeMetastoreService.java index 9d16533..4780955 100644 --- a/lens-server-api/src/main/java/org/apache/lens/server/api/metastore/CubeMetastoreService.java +++ b/lens-server-api/src/main/java/org/apache/lens/server/api/metastore/CubeMetastoreService.java @@ -536,6 +536,9 @@ public interface CubeMetastoreService extends LensService, SessionValidator { void dropPartitionFromStorageByFilter(LensSessionHandle sessionid, String cubeTableName, String storageName, String filter) throws LensException; + void dropPartitionFromStorageByFilter(LensSessionHandle sessionid, + String cubeTableName, String storageName, String filter, String updatePeriod) throws LensException; + /** * Get flattened columns - all columns of table + all reachable columns * http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/lens-server/src/main/java/org/apache/lens/server/metastore/CubeMetastoreServiceImpl.java ---------------------------------------------------------------------- diff --git a/lens-server/src/main/java/org/apache/lens/server/metastore/CubeMetastoreServiceImpl.java b/lens-server/src/main/java/org/apache/lens/server/metastore/CubeMetastoreServiceImpl.java index 0a8635c..74806af 100644 --- a/lens-server/src/main/java/org/apache/lens/server/metastore/CubeMetastoreServiceImpl.java +++ b/lens-server/src/main/java/org/apache/lens/server/metastore/CubeMetastoreServiceImpl.java @@ -781,6 +781,10 @@ public class CubeMetastoreServiceImpl extends BaseLensService implements CubeMet public void dropPartitionFromStorageByFilter(LensSessionHandle sessionid, String cubeTableName, String storageName, String filter) throws LensException { + dropPartitionFromStorageByFilter(sessionid, cubeTableName, storageName, filter, null); + } + public void dropPartitionFromStorageByFilter(LensSessionHandle sessionid, String cubeTableName, + String storageName, String filter, String updatePeriodString) throws LensException { try (SessionContext ignored = new SessionContext(sessionid)){ Set<String> storageTables = getAllTablesForStorage(sessionid, cubeTableName, storageName); List<Partition> partitions = new ArrayList<>(); @@ -788,11 +792,15 @@ public class CubeMetastoreServiceImpl extends BaseLensService implements CubeMet for (String tableName : storageTables) { partitions.addAll(msClient.getPartitionsByFilter(tableName, filter)); } + if (updatePeriodString!=null) { + partitions.removeIf(part -> !part.getParameters().get(MetastoreConstants.PARTITION_UPDATE_PERIOD). + equals((updatePeriodString.toUpperCase()))); + } for (Partition part : partitions) { try { Map<String, Date> timeSpec = new HashMap<>(); Map<String, String> nonTimeSpec = new HashMap<>(); - UpdatePeriod updatePeriod = populatePartSpec(part, timeSpec, nonTimeSpec); + UpdatePeriod updatePeriod= populatePartSpec(part, timeSpec, nonTimeSpec); msClient.dropPartition(cubeTableName, storageName, timeSpec, nonTimeSpec, updatePeriod); } catch (HiveException e) { if (!(e.getCause() instanceof NoSuchObjectException)) { http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/lens-server/src/main/java/org/apache/lens/server/metastore/MetastoreResource.java ---------------------------------------------------------------------- diff --git a/lens-server/src/main/java/org/apache/lens/server/metastore/MetastoreResource.java b/lens-server/src/main/java/org/apache/lens/server/metastore/MetastoreResource.java index 0af6a34..8818844 100644 --- a/lens-server/src/main/java/org/apache/lens/server/metastore/MetastoreResource.java +++ b/lens-server/src/main/java/org/apache/lens/server/metastore/MetastoreResource.java @@ -1022,10 +1022,11 @@ public class MetastoreResource { public APIResult dropPartitionsOfFactStorageByFilter(@QueryParam("sessionid") LensSessionHandle sessionid, @PathParam("factName") String factName, @PathParam("storage") String storage, - @QueryParam("filter") String filter) throws LensException { + @QueryParam("filter") String filter, + @QueryParam("updatePeriod") String updatePeriod) throws LensException { checkSessionId(sessionid); try { - getSvc().dropPartitionFromStorageByFilter(sessionid, factName, storage, filter); + getSvc().dropPartitionFromStorageByFilter(sessionid, factName, storage, filter, updatePeriod); } catch (LensException exc) { log.warn("Got exception while dropping partition.", exc); return partial(processLensException(exc)); http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java ---------------------------------------------------------------------- diff --git a/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java b/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java index ab24033..fdf4694 100644 --- a/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java +++ b/lens-server/src/test/java/org/apache/lens/server/metastore/TestMetastoreService.java @@ -2527,7 +2527,7 @@ public class TestMetastoreService extends LensJerseyTest { } private XPartition createPartition(String cubeTableName, Date partDate) { - return createPartition(cubeTableName, partDate, "dt"); + return createPartition(cubeTableName, partDate, "dt", null); } private XTimePartSpecElement createTimePartSpecElement(Date partDate, String timeDimension) { @@ -2539,11 +2539,17 @@ public class TestMetastoreService extends LensJerseyTest { private XPartition createPartition(String cubeTableName, Date partDate, final String timeDimension) { - return createPartition(cubeTableName, Lists.newArrayList(createTimePartSpecElement(partDate, timeDimension))); + return createPartition(cubeTableName, partDate, timeDimension, null); } - private XPartition createPartition(String cubeTableName, final List<XTimePartSpecElement> timePartSpecs) { + private XPartition createPartition(String cubeTableName, Date partDate, final String timeDimension, + String updatePeriod) { + return createPartition(cubeTableName, Lists.newArrayList( + createTimePartSpecElement(partDate, timeDimension)), updatePeriod); + } + private XPartition createPartition(String cubeTableName, final List<XTimePartSpecElement> + timePartSpecs, String updatePeriod) { XPartition xp = cubeObjectFactory.createXPartition(); xp.setLocation(new Path(new File("target").getAbsolutePath(), "part/test_part").toString()); xp.setFactOrDimensionTableName(cubeTableName); @@ -2554,10 +2560,19 @@ public class TestMetastoreService extends LensJerseyTest { for (XTimePartSpecElement timePartSpec : timePartSpecs) { xp.getTimePartitionSpec().getPartSpecElement().add(timePartSpec); } - xp.setUpdatePeriod(XUpdatePeriod.HOURLY); + if (updatePeriod==null) { + xp.setUpdatePeriod(XUpdatePeriod.HOURLY); + } else { + XUpdatePeriod updatePeriod1=XUpdatePeriod.valueOf(updatePeriod.toUpperCase()); + xp.setUpdatePeriod(updatePeriod1); + } return xp; } + private XPartition createPartition(String cubeTableName, final List<XTimePartSpecElement> timePartSpecs) { + return createPartition(cubeTableName, timePartSpecs, null); + } + @Test(dataProvider = "mediaTypeData") public void testLatestDateWithInputTimeDimAbsentFromAtleastOneFactPartition(MediaType mediaType) throws Exception { @@ -2704,6 +2719,7 @@ public class TestMetastoreService extends LensJerseyTest { setCurrentDatabase(DB, mediaType); createStorage("S1", mediaType); createStorage("S2", mediaType); + createStorage("S3", mediaType); try { @@ -2717,6 +2733,7 @@ public class TestMetastoreService extends LensJerseyTest { f.getStorageTables().getStorageTable().add(createStorageTblElement("S1", table, "HOURLY")); f.getStorageTables().getStorageTable().add(createStorageTblElement("S2", table, "DAILY")); f.getStorageTables().getStorageTable().add(createStorageTblElement("S2", table, "HOURLY")); + f.getStorageTables().getStorageTable().add(createStorageTblElement("S3", table, "HOURLY", "DAILY")); APIResult result = target() .path("metastore") .path("facts").queryParam("sessionid", lensSessionId) @@ -2903,6 +2920,47 @@ public class TestMetastoreService extends LensJerseyTest { partitions = partitionsElement.getValue(); assertNotNull(partitions); assertEquals(partitions.getPartition().size(), 0); + + //adding 2 partition daily and hourly on S3 storage + + xp = createPartition(table, partDate, "dt"); + APIResult partAddResult1 = target().path("metastore/facts/").path(table).path("storages/S3/partition") + .queryParam("sessionid", lensSessionId).request(mediaType) + .post(Entity.entity(new GenericEntity<JAXBElement<XPartition>>(cubeObjectFactory.createXPartition(xp)) { + }, mediaType), APIResult.class); + assertSuccess(partAddResult1); + + xp2 = createPartition(table, partDate, "dt", "daily"); + APIResult partAddResult2 = target().path("metastore/facts/").path(table).path("storages/S3/partition") + .queryParam("sessionid", lensSessionId).request(mediaType) + .post(Entity.entity(new GenericEntity<JAXBElement<XPartition>>(cubeObjectFactory.createXPartition(xp2)) { + }, mediaType), APIResult.class); + assertSuccess(partAddResult2); + + String filter="dt<='" + HOURLY.format(partDate) + "'"; + + //deleting partition based on filter and updatePeriod + + dropResult = target().path("metastore/facts").path(table).path("storages/S3/partitions") + .queryParam("sessionid", lensSessionId).queryParam("filter", filter) + .queryParam("updatePeriod", "hourly").request(mediaType).delete(APIResult.class); + + assertSuccess(dropResult); + + + // Verify only hourly partition was dropped + partitionsElement = target().path("metastore/facts").path(table).path("storages/S3/partitions") + .queryParam("sessionid", lensSessionId) + .queryParam("filter", "dt<='" + HOURLY.format(partDate) + "'") + .request(mediaType).get(new GenericType<JAXBElement<XPartitionList>>() { + }); + + + partitions = partitionsElement.getValue(); + assertNotNull(partitions); + assertEquals(partitionsElement.getValue().getPartition().get(0).getUpdatePeriod(), XUpdatePeriod.DAILY); + + } finally { setCurrentDatabase(prevDb, mediaType); dropDatabase(DB, mediaType); http://git-wip-us.apache.org/repos/asf/lens/blob/cdac4087/src/site/apt/user/cli.apt ---------------------------------------------------------------------- diff --git a/src/site/apt/user/cli.apt b/src/site/apt/user/cli.apt index 1653e9f..12bc88c 100644 --- a/src/site/apt/user/cli.apt +++ b/src/site/apt/user/cli.apt @@ -389,49 +389,55 @@ User CLI Commands *--+--+ |<<Command>>|<<Description>>| *--+--+ -|schema/create schema [--db] \<database-to-create-schema-in\> [--path/--file] \<schema-directory\>|Parses the specified resource file and executes commands for creation/updation of schema \ | -| |Expected\ structure\ is\ \ | -| |. \ | -| |\|--\ storages \ | -| |\|\ \ \|--\ storage1.xml \ | -| |\|\ \ \|--\ storage2.xml \ | -| |\| \ | -| |\|--\ dimensions \ | -| |\|\ \ \|--\ dim1.xml \ | -| |\|\ \ \|--\ dim2.xml \ | -| |\| \ | -| |\|--\ cubes \ | -| |\|\ \ \|--\ base \ | -| |\|\ \ \|\ \ \|--\ base_cube1.xml \ | -| |\|\ \ \|\ \ \|--\ base_cube2.xml \ | -| |\|\ \ \| \ | -| |\|\ \ \|--\ derived \ | -| |\|\ \ \|\ \ \|--\ derived_cube1.xml \ | -| |\|\ \ \|\ \ \|--\ derived_cube2.xml \ | -| |\|\ \ \| \ | -| |\|\ \ \|--\ independent_cube1.xml \ | -| |\|\ \ \|--\ independent_cube2.xml \ | -| |\| \ | -| |\|--\ dimensiontables \ | -| |\|\ \ \|--\ dimtable1.xml \ | -| |\|\ \ \|--\ dimtable2.xml \ | -| |\| \ | -| |\|--\ dimtables \ | -| |\|\ \ \|--\ dimtable3.xml \ | -| |\|\ \ \|--\ dimtable4.xml \ | -| |\| \ | -| |\|--\ facts \ | -| |\ \ \ \|--\ fact1.xml \ | -| |\ \ \ \|--\ fact2.xml \ | -| | \ | -| | \ | -| |If\ your\ cubes\ are\ divided\ between\ base\ and\ derived\ cubes, \ | -| |it\ makes\ sense\ to\ seperate\ into\ two\ directories,\ since\ derived\ cubes\ can't\ be\ created\ unless\ base\ cube\ exists.\ | -| |In\ the\ other\ case\ you\ can\ keep\ them\ in\ the\ cubes\ directory\ itself. \ | -| |For\ dimtables,\ you\ can\ keep\ your\ schema\ files\ in\ a\ directory\ named\ either\ dimtables\ or\ dimensiontables. \ | -| |Each\ of\ these\ directories\ is\ optional\ and\ the\ order\ of\ processing\ is\ top\ to\ bottom. \ | -| |CLI\ will\ let\ you\ know\ in\ case\ of\ any\ errors\ and\ proceed\ further\ without\ failing\ in\ between. \ | +|schema/create schema [--db] \<database-to-create-schema-in\> [--path/--file] \<schema-directory\> [[--type] \<schema-type-filter\>] [[--name] \<file-name-filter\>]|Parses the specified resource file and executes commands for creation/updation of schema. If <<<schema-type-filter>>> is provided, only schema types matching that will be worked upon. If <<<file-name-filter>>> is provided, then only those files that contain the filter value will be worked upon. \ | +| |Expected\ directory\ structure\ is\ \ | +| |. \ | +| |\|--\ storages \ | +| |\|\ \ \|--\ storage1.xml \ | +| |\|\ \ \|--\ storage2.xml \ | +| |\| \ | +| |\|--\ dimensions \ | +| |\|\ \ \|--\ dim1.xml \ | +| |\|\ \ \|--\ dim2.xml \ | +| |\| \ | +| |\|--\ cubes \ | +| |\|\ \ \|--\ base \ | +| |\|\ \ \|\ \ \|--\ base_cube1.xml \ | +| |\|\ \ \|\ \ \|--\ base_cube2.xml \ | +| |\|\ \ \| \ | +| |\|\ \ \|--\ derived \ | +| |\|\ \ \|\ \ \|--\ derived_cube1.xml \ | +| |\|\ \ \|\ \ \|--\ derived_cube2.xml \ | +| |\|\ \ \| \ | +| |\|\ \ \|--\ independent_cube1.xml \ | +| |\|\ \ \|--\ independent_cube2.xml \ | +| |\| \ | +| |\|--\ dimensiontables \ | +| |\|\ \ \|--\ dimtable1.xml \ | +| |\|\ \ \|--\ dimtable2.xml \ | +| |\| \ | +| |\|--\ dimtables \ | +| |\|\ \ \|--\ dimtable3.xml \ | +| |\|\ \ \|--\ dimtable4.xml \ | +| |\| \ | +| |\|--\ facts \ | +| |\ \ \ \|--\ fact1.xml \ | +| |\ \ \ \|--\ fact2.xml \ | +| |\|\ \ \| \ | +| |\|\ \ \|--\ virtual \ | +| |\|\ \ \|\ \ \|--\ virtual_fact1.xml \ | +| |\|\ \ \|\ \ \|--\ virtual_fact2.xml \ | +| |\|\ \ \| \ | +| | \ | +| | \ | +| |If\ your\ cubes\ are\ divided\ between\ base\ and\ derived\ cubes, \ | +| |it\ makes\ sense\ to\ seperate\ into\ two\ directories,\ since\ derived\ cubes\ can't\ be\ created\ unless\ base\ cube\ exists. \ | +| |In\ the\ other\ case\ you\ can\ keep\ them\ in\ the\ cubes\ directory\ itself. \ | +| |For\ dimtables,\ you\ can\ keep\ your\ schema\ files\ in\ a\ directory\ named\ either\ dimtables\ or\ dimensiontables. \ | +| |Each\ of\ these\ directories\ is\ optional\ and\ the\ order\ of\ processing\ is\ top\ to\ bottom. \ | +| |CLI\ will\ let\ you\ know\ in\ case\ of\ any\ errors\ and\ proceed\ further\ without\ failing\ in\ between. \ | *--+--+ <<Lens Schema Commands>> -=== \ No newline at end of file +=== +