• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1941
  • Last Modified:

how to read a pervasive ddf with out using pervasive

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
hainansyndrome
Asked:
hainansyndrome
  • 10
  • 7
  • 3
1 Solution
 
hainansyndromeAuthor Commented:
also i cant use PCC at all , so i have to be able to read the File.ddf
0
 
mirtheilCommented:
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
 
Bill BachPresidentCommented:
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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
hainansyndromeAuthor Commented:
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
 
Bill BachPresidentCommented:
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
 
hainansyndromeAuthor Commented:
well what i really need is an example in vb.net but ill try to muddle throught the deveolper section
0
 
mirtheilCommented:
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
 
hainansyndromeAuthor Commented:
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
 
mirtheilCommented:
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
 
hainansyndromeAuthor Commented:
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
 
mirtheilCommented:
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
 
hainansyndromeAuthor Commented:
so i suppliment file.ddf for the databasename?
0
 
mirtheilCommented:
DTO requires a database name.  It can't work directly with the FILE.DDF by itself.  
0
 
hainansyndromeAuthor Commented:
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
 
mirtheilCommented:
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
 
hainansyndromeAuthor Commented:
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
 
mirtheilCommented:
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
 
hainansyndromeAuthor Commented:
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
 
Bill BachPresidentCommented:
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
 
hainansyndromeAuthor Commented:
nothign against Mithrel, Btrieve is just hard to comprehend
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 10
  • 7
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now