Solved

how to read a pervasive ddf with out using pervasive

Posted on 2010-09-03
20
1,534 Views
Last Modified: 2012-06-27
I need to be able to read a file.ddf to get the path of a specific file in the ddf,
since the path changes I need to be able to read the ddf  to a dataset so I can get the whole path from what ever field in the dataset
0
Comment
Question by:hainansyndrome
  • 10
  • 7
  • 3
20 Comments
 

Author Comment

by:hainansyndrome
ID: 33600267
also i cant use PCC at all , so i have to be able to read the File.ddf
0
 
LVL 18

Expert Comment

by:mirtheil
ID: 33602973
WHat interface are you using?  Using a SQL interface like ADO.NET, ODBC, or OLEDB, you can issue a "SELECT * FROM X$FILE WHERE XF$NAME = 'yourtablename'"query. The XF$LOC field returns the filename (and any path).  
Most DDFs do not store a path though which means the DDF and data file are in the same directory.
0
 
LVL 28

Expert Comment

by:Bill Bach
ID: 33603073
You can also open the FILE.DDF table directly at the Btrieve layer. It should have an owner name, but if security is not enables, then you'll have read-only access. The table definition is defined in the online manuals, so you can read the FILE.DDF and find the right offset to Xf$Loc.

If the DDFs do not store the path, then you also may need to query the path information from the Named Database. This can be done with the DTI or DTO interfaces.
0
 

Author Comment

by:hainansyndrome
ID: 33603113
can you point me to some info a bout opeing the file.ddf onthe btrieve level, that sounds like what i need, i would only need read only access

0
 
LVL 28

Expert Comment

by:Bill Bach
ID: 33603153
You can find numerous examples on www.pervasive.com in the "DeveloperZone" section of the web site. The sample code will vary widely based on your coding language.

The logic is simple, though:
  FileOpen on FILE.DDF
  GetEqual on Key w for the name of the table you are looking up
  FileClose
Then, you can parse the returning data buffer to extract the xf$loc field.

If you need a detailed example in C, let me know and I can provide that on Tuesday.
0
 

Author Comment

by:hainansyndrome
ID: 33603189
well what i really need is an example in vb.net but ill try to muddle throught the deveolper section
0
 
LVL 18

Expert Comment

by:mirtheil
ID: 33603252
In the .NET section (http://ww1.pervasive.com/developerzone/platforms/net.asp), there are two VB.NET and Btrieve API samples.  They are called "VB.NET Btrieve API 1"  and "VB.NET Btrieve API 2".  
0
 

Author Comment

by:hainansyndrome
ID: 33605089
ok i got the cod ebut it is a bit over my head
anyone know of code examples of reading in the File.ddf in dotnet?
0
 
LVL 18

Accepted Solution

by:
mirtheil earned 500 total points
ID: 33605246
The best way to get the information you are trying to get is to use the ODBC, OLEDB, or ADO.NET provider and issue the SELECT * I had posted previously.  THere is another method I had forgotten.  You can use DTO if you have a recent version of PSQL.  

What version of Pervasive are you using?  
I don't have a sample for using Btrieve API in .NET to read the file.ddf but I do have a

Attached is a C# sample that does get the table name and table location based on a set of DDFs (FILE.DDF, FIELD.DDF, and INDEX.DDF).  You would need to add the DTO library as a Reference within your C# project.  
using System;

using DTOLib;



namespace dtoTest

{

	/// <summary>

	/// Summary description for Class1.

	/// </summary>

	class Class1

	{

		/// <summary>

		/// The main entry point for the application.

		/// </summary>

		[STAThread]

		static void Main(string[] args)

		{

			string compName = null;

			string userName = null;

			string password = null;

			string dbn = null;



			DTOLib.dtoResult result ;

			if (args.LongLength < 1)

			{

				Console.WriteLine("Invalid options.\n");

				return;

			}

			if (args.LongLength == 4)

			{

				compName = args[0].ToString();

				userName = args[1].ToString();

				password = args[2].ToString();

				dbn = args[3].ToString();

			}

			Console.WriteLine("Pervasive Sample using DTO and C#");

			Console.WriteLine("Lists tables defined in specified DBN.");

			Console.WriteLine("Copyright 2003 Pervasive Software");

			DtoSession mDtoSession = new DTOLib.DtoSession();

			try

			{

				result = mDtoSession.Connect (compName, userName, password);

				if (result != 0)

				{

					Console.WriteLine("Error connecting to server.  Error code:");

				}

				else

				{

					Console.WriteLine("Connected to " + mDtoSession.ServerName );

					DtoDatabase mDtoDatabase = new DTOLib.DtoDatabaseClass();

					int dbnCount =  mDtoSession.Databases.Count;

					for (int iCount = 1; iCount <= dbnCount; iCount++)

					{

						if (dbn.ToUpper() == mDtoSession.Databases[iCount].Name.ToString().ToUpper())

						{

							// We found it. Now we need to iterate through the tables.

							mDtoDatabase = mDtoSession.Databases[iCount];

							

							DtoDictionary mDtoDictionary = new DTOLib.DtoDictionaryClass();

							DtoTables mDtoTables = new DTOLib.DtoTablesClass();

							DtoTable mDtoTable = new DTOLib.DtoTableClass();

							string sPath;

							sPath = mDtoSession.Databases[iCount].DdfPath.ToString();

							result = mDtoDictionary.Open(sPath,"","");

						

							if (result != 0)

								Console.WriteLine("Error Opening Dictionary.  Error code: " + result.ToString());

							else

							{

								//Dictionary is open. Now let's get the tables.

								int tblCount;

								tblCount = mDtoDictionary.Tables.Count;

								Console.WriteLine("Found " + tblCount.ToString() + " tables.");

								for (int iTblCount = 1; iTblCount <= tblCount;iTblCount++)

								{

									mDtoTable = mDtoDictionary.Tables[iTblCount];

									Console.WriteLine("Table Name: " + mDtoTable.Name.ToString());

									Console.WriteLine("Table Location: " + mDtoTable.Location.ToString());

								}

							}

						}

						Console.WriteLine("");

					}



					result = mDtoSession.Disconnect();

				}

			}

			catch (Exception e1)

			{

				Console.WriteLine(e1.Message.ToString());

			}

		}

	}

	}

Open in new window

0
 

Author Comment

by:hainansyndrome
ID: 33607866
ok what fo you pass into string[] args
looks like a string array

and we are using anywhere from psql 7.9 to the newest
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 18

Expert Comment

by:mirtheil
ID: 33608116
The way that sample is written, it compiles as a console application.  You would pass the parameters as follows:

dtoTest.exe <computername> <adminuser> <adminpassword> <PSQL DBName>

For example, to connect to a remote machine named "server" with the Administrator user and list the DEMODATA tables you would call it like:
dtoTest.exe server Administrator password DEMODATA

This is  a sample that I received from Pervasive many years ago and I used parts of it in a project at the time.  
0
 

Author Comment

by:hainansyndrome
ID: 33608154
so i suppliment file.ddf for the databasename?
0
 
LVL 18

Expert Comment

by:mirtheil
ID: 33608235
DTO requires a database name.  It can't work directly with the FILE.DDF by itself.  
0
 

Author Comment

by:hainansyndrome
ID: 33608263
ok the DTO is useless to me

i dont want to read a database
i want to read the ddf to get the paths to the databases

server has dat files
work stations have ddf with the paths to the ddf hard coded
i need to basicallg read file.ddf into a dataset
0
 
LVL 18

Expert Comment

by:mirtheil
ID: 33608293
The only way to read the FILE.DDF directly is through Btrieve API. We've explained how to use the Btrieve API to read the FILE.DDF.  

What exactly are you trying to do?   You said you are trying to get the path to the databases.  FILE.DDF doesn't store database information.  It stores information linking table names to underlying Btrieve data files.  What are you going to do with the information you get from the FILE.DDF?
0
 

Author Comment

by:hainansyndrome
ID: 33608322
this particular software does store a hard coded path to the .dat files in the file.ddf

use that information to copy the .dat files
0
 
LVL 18

Expert Comment

by:mirtheil
ID: 33612972
So why are the DDF files on the workstation and not on the server with the data files?  They really belong on the server in the same directory as the data files. Ideally they wouldn't have any paths either.  
0
 

Author Comment

by:hainansyndrome
ID: 33617454
they are on both places
the ddf files on the server reference the local path to the .dat files

then on the workstation the server is mapped as drive M
then the workstation DDFs reference the path to the dat files using M drive
0
 
LVL 28

Expert Comment

by:Bill Bach
ID: 33617696
Strange.  Most applications do this with an INI file or registry entry.  However, you need to play what you're dealt.

I admit that accessing Btrieve directly from VB.NET is NOT straightforward.  Mainly due to the fact that all Btrieve memory buffers are byte oriented, Microsoft added a lot of complexity to the VB world when they started aligning data on longword (4-byte) boundaries, which broke a lot of applications.  Then, they added more "benefits" in the .NET world which made low-level access even more difficult.

Like it or not, it's time to hunker down and go through the sample code likes that Mirtheil provided.  The README.TXT included with the ZIP file contains some good information -- take some time to review that.  Then, look through the code, as there is some documentation there, too.  

When you get into it, you'll essentially need the OPEN call, followed by a GetEqual on Key Number 1 (the Xf$Name field, or the table name you are looking for), and then the CLOSE operation.  Once you've read the buffer into a block of bytes, you'll then need to parse it into the appropriate fields (i.e. Xf$Loc for the file path).

As I indicated, this is difficult, but not impossible, from VB.NET.

Another possibility would be to write a much simpler function call in C/C++ and build it into a DLL, then call that DLL from your VB.NET environment.  Be sure, again, to compile your code for byte alignment of data structures.
0
 

Author Closing Comment

by:hainansyndrome
ID: 33694565
nothign against Mithrel, Btrieve is just hard to comprehend
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

I annotated my article on ransomware somewhat extensively, but I keep adding new references and wanted to put a link to the reference library.  Despite all the reference tools I have on hand, it was not easy to find a way to do this easily. I finall…
Shadow IT is coming out of the shadows as more businesses are choosing cloud-based applications. It is now a multi-cloud world for most organizations. Simultaneously, most businesses have yet to consolidate with one cloud provider or define an offic…
Video by: Steve
Using examples as well as descriptions, step through each of the common simple join types, explaining differences in syntax, differences in expected outputs and showing how the queries run along with the actual outputs based upon a simple set of dem…
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now