Biztalk- flat file schema definitions - schema

I have defined a flat file schema which works fine. However, I got now a new requirement for this schema: It has to support future potential additional fields in the end of the records.
The solution I used is quit "ugly". I added an additional filler at the end of the record and configured it as "minOccurs = 0" and set Allow early termination of optional fileds to true.
This works but I don't like it.
It seems to me that there must be a property for ignoring any additional fields after the last one, so I won't need this filler field.
Does anyone familiar with such option/ property?
Thanks all.

Nope, what you've done is the correct way to handle this situation. Beauty is in the eye of the beholder.
The Flat File Parser requires all possible content be defined in the schema so it doesn't ever have to 'guess' what's next.

When a flat file changes, the schema must change as well. That is part of the job for a BizTalk developer.
You can't anticipate changes to the flat file inside your schema. With the filler field you have now, what are you going to do if 2 extra fields appear and have to be used? How will you get the data in, say, a mapping?
This is the way the flat file parser works, everything has to be well defined and if the specs change you must update your schemas. There is no magic here to make it all completely dynamic. Unless if you were to write a custom flat file disassembler from scratch that supports it, but good luck with that.

Related

Read Excel Files from External Tables

I am tasked to create a template that will be Filled up by Business Users with Employee Information, then our program will load this into the Database using External Tables.
However, our Business Users constantly change the template by adding, removing or reordering fields.
I am convinced to use XLSX instead of CSV so that I can lock the Column Headers so they cannot remove, add and reorder the columns.
However, When i query the External Table, it shows Non-ASCII Characters when reading XLSX because its in Binary.
How can i do either of the following?
Effectively Read Excel Files from External Tables
Lock the Headers of CSV Files?
What you have here is a political problem, but you are looking for a technical fix. Not a good fit.
The problem comes in two halves:
Somebody decided it was a good idea to collect user input in a spreadsheet, which it is generally not.
Users are fiddling with the input format, which they should not.
Fixes are:
Strictly enforce the data structure. Reject any CSV which doesn't natch and make the users edit them. They will quickly tire of tweaking the spreadsheets when they realise they're just creating more work for themselves. But they will also get resentful, so consider ...
Building a data input screen. It's pretty simple to knock up a spreadsheet-like grid UI. You don't need anything complicated in Java: Oracle's Apex is intended for exactly this sort of thing. Find out more.
However, if you are stuck with Excel as a UI I suggest you have a look at Anton Scheffer's excellent PLSQL as_read_xlsx package on the Amis site. Check it out. You'll probably need to replace your external table with a view over a table (perhaps pipelined) function.

Liquibase load data in a format other than CSV

With the load data option that Liquibase provides, one can specify seed data in a CSV format. Is there a way I can provide say, a JSON or XML file with data that Liquibase would understand?
The use case is we are trying to put in some sample data which is hierarchical. E.g. Category - Subcategory relation which would require putting in parent id for all related categories. If there is a way to avoid including the ids in the seed data via say, JSON.
{
"MainCat1": ["SubCat11", "SubCat12"],
"MainCat2": ["SubCat21", "SubCat22"]
}
Very likely to have this as not supported (couldn't make Google help me) but is there a way to write a plugin or something that does this? Pointer to a guide (if any) would help.
NOTE: This is not about specifying the change log in that format.
This not currently supported and supporting it robustly would be pretty difficult. The main difficultly lies in the fact that Liquibase is designed to be database-platform agnostic, combined with the design goal of being able to generate the SQL required to do an operation without actually doing the operation live.
Inserting data like you want without knowing the keys and just generating SQL that could be run later is going to be very difficult, perhaps even impossible. I would suggest approaching Nathan, who is the main developer for Liquibase, more directly. The best way to do that might be through the JIRA bug database for Liquibase.
If you want to have a crack at implementing it, you could start by looking at the code for the LoadDataChange class (source in Github), which is where the CSV support currently lives.

How to add my own PRAGMA statements in SQLite to store custom meta data

I want to store meta data like author name, copyright, source to my SQLite DB without creating a new table. I found out we can use PRAGMA statements to set some values.. I would like to store my own custom name and value ... How to create custom PRAGMA statement? http://www.sqlite.org/pragma.html
Has anyone done this before? The doc says..
"The C-language API for SQLite provides the SQLITE_FCNTL_PRAGMA file control which gives VFS implementations the opportunity to add new PRAGMA statements or to override the meaning of built-in PRAGMA statements."
Please let me know how can I achieve this?
The built-in PRAGMAs that store their value in the database do so in the database header.
There is not enough space to add custom values.
You have no choice but to create a new table.
Not sure if this is enough for you, but I use user_version to keep track of the last schema check.
What I do is save the timestamp it was last checked against the code schema. If it's been 24h, or 5m, or whatever, I do a re-check and update stuff. I only need 1 32b int for that, so it's perfect. If you need more, this is not it.
More info on user_version here (PRAGMA schema_version) and here (db reserved header space)
Take a look at the new Checksum VFS Shim for an example of a VFS adding a custom pragma.
The source code is linked on the page above, but here is it again, just in case.
But of course, you cannot store additional information, except via tables.
So while the above does show how to implement a custom pragma, your actual
end-goal is not possible, since the header is fixed and reserved for SQLite itself. If you have a table, why have a pragma then?
The answer from ddevienne about looking at the VFS Shim sources is the step in the right direction, but the comment about impossibility to store your own data is partially correct (I could not add a comment due to my early insufficient reputation so posting as an answer). It's your own vfs so you're free to organize the data as you wish. xRead and xWrite interfaces just assumes the sqlite own positional logic, but you can reserve an area at the start of the file for your own purposes and translate the positions accordingly. I can confirm this works since implemented an vfs reserving a small area at the start using this technique. But there are consequences, in this case the file won't be compatible with conventional sqlite tools and libraries.

Alternatives to using RFile in Symbian

This question is in continuation to my previous question related to File I/O.
I am using RFile to open a file and read/write data to it. Now, my requirement is such that I would have to modify certain fields within the file. I separate each field within a record with a colon and each record with a newline. Sample is below:
abc#def.com:Albert:1:2
def#ghi.com:Alice:3:1
Suppose I want to replace the '3' in the second record by '2'. I am finding it difficult to overwrite specific field in the file using RFile because RFile does not provide its users with such facility.
Due to this, to modify a record I have to delete the contents of the file and serialize ( that is loop through in memory representation of records and write to the file ). Doing this everytime there is a change in a record's value is quite expensive as there are hundreds of records and the change could be quite frequent.
I searched around for alternatives and found CPermanentFileStore. But I feel the API is hard to use as I am not able to find any source on the Internet that demonstrates its use.
Is there a way around this. Please help.
Depending on which version(s) of Symbian OS you are targetting, you could store the information in a relational database. Since v9.4, Symbian OS includes an SQL implementation (based on the open source SQLite engine).
Using normal files for this type of records takes a lot of effort no matter the operating system. To be able to do this efficiently you need to reserve space in the file for expansion of each record - otherwise you need to rewrite the entire file if a record value changes from say 9 to 10. Also storing a lookup table in the file will make it possible to jump directly to a record using RFile::Seek.
The CPermamanentFileStore simplifies the actual reading and writing of the file but basically does what you have to do yourself otherwise. A database may be a better choice in this instance. If you don't want to use a database I think using stores would be be a better solution.

What's the best way to deprecate a column in a database schema?

After reading through many of the questions here about DB schema migration and versions, I've come up with a scheme to safely update DB schema during our update process. The basic idea is that during an update, we export the database to file, drop and re-create all tables, and then re-import everything. Nothing too fancy or risky there.
The problem is that this system is somewhat "viral", meaning that it is only safe to add columns or tables, since removing them would cause problems when re-importing the data. Normally, I would be fine just ignoring these columns, but the problem is that many of the removed items have actually been refactored, and the presence of the old ones in the code fools other programmers into thinking that they can use them.
So, I would like to find a way to be able to mark columns or tables as deprecated. In the ideal case, the deprecated objects would be marked while updating the schema, but then during the next update our backup script would simply not SELECT the objects which have been marked in this way, allowing us to eventually phase out these parts of the schema.
I have found that MySQL (and probably other DB platforms too, but this is the one we are using) supports the COLUMN attribute to both fields and tables. This would be perfect, except that I can't figure out how to actually use it in a meaningful manner. How would I go about writing an SQL query to get all column names which do not contain a comment matching text containing the word "deprecated"? Or am I looking at this problem all wrong, and missing a much better way to do this?
Maybe you should refactor to use views over your tables, where the views never include the deprocated columns.
"Deprecate" usually means (to me at least) that something is marked for removal at some future date, should not used by new functionality and will be removed/changed in existing code.
I don't know of a good way to "mark" a deprecated column, other than to rename it, which is likely to break things! Even if such a facility existed, how much use would it really be?
So do you really want to deprecate or remove? From the content of your question, I'm guessing the latter.
I have the nasty feeling that you may be in one of those "if I wanted to get to there I wouldn't start from here" situations. However, here are some ideas that spring to mind:
Read Recipes for Continuous Database Integration which seems to address much of your problem area
Drop the column explicitly. In MySQL 5.0 (and even earlier?) the facility exists as part of DDL: see the ALTER TABLE syntax.
Look at how ActiveRecord::Migration works in Ruby. A migration can include the "remove_column" directive, which will deal with the problem in a platform-appropriate way. It definitely works with MySQL, from personal experience.
Run a script against your export to remove the column from the INSERT statements, both column and values lists. Probably quite viable if your DB is fairly small, which I'm guessing it must be if you export and re-import it as described.