Database Front end question

I am thinking of creating a shareware database application and need some expert Doper advice!

I decided to use PostgreSQL even though I have no experience with that particular database platform (although I’m good with relational database design).

So how do I create a nice user interface for the tables that I make in Postgre? I don’t want to use Access because others may not have purchased it. I was looking into OpenOffice. Does that have a form & macro functionality to make a user interface. If it does not, is there any other software that I can use to create the forms & reports to a Postgre db?

It’s safe to say everyone has a browser, so go web-based. Do it all for free.

MySQL database, Apache web server, Coldfusion application server. Your code will be SQL, Coldfusion, with a little bit a JavaScript.

:wink:

Last I checked, sending out the Access runtime module with an Access application was legal.

That’s something I never thought about. Isn’t Coldfusion for client/server apps though? The thing I have in mind is a desktop application. Is Coldfusion applicable for this?

Never used it though, what’s the learning curve like?

For ASP, you do need to have server software installed on the machine that will be doing the ASP processing. Coldfusion is a pretty similar technology, so I’d assume it has a similar requirement–but I don’t know for sure.

The learning curve should be pretty short if you’ve done programming before, and not incredibly painful if you haven’t.

Yes, ColdFusion does require you to run an application on a server. On the other hand, its mostly a combination of html and sql and may be easier to code than learning asp.

How is this application going to be used?

Is one database going to be used for all transactions or is each client going to have their own copy? For one master database you would need a robust server (which PostgreSQL should qualify as) which the clients would interact with. PHP/ASP etc would work well in this case as it’s fast and requires nothing more than a web browser for the client to use.
Installing the database along with the front-end on a client’s computer (which it sounds like you’re thinking of) requires not only the database server but the application to use it. Access works as both of these in one with both the tables & queries and the forms. Outside of access you start to find more divergent technologies which specialize on one over the other. What is this application going to do?

Local shareware application with only a single user? I’d go with the brain-dead approach of ultra-RAD: VB front end with Access back end. Really, within about two days you could be almost finished. And the users don’t need Access at all.

If you want it to be a real application, however, VB on top of Access is a bit of an amateur approach. Even still, it is simple and effective. If you just don’t like Access, you could do VB on top of whatever back end you want.

There’s also Visual FoxPro, which has a couple benefits, despite its antiquated data system. The front end component compiles to EXE, unlike Access. And the install can be completely non-intrusive, unlike VB. I once developed a pretty intensive VFP app that ended up being quite powerful, very tied in to the system, and had no installation outside of its home folder.

All reports could be directed to Excel, Acrobat, or a printer, and it trawled for data in (and managed) countless legacy Clipper/DOS apps. But the install simply required a home folder on the user’s computer. No registering of components or anything. Ran like a charm on a system that had no VFP or much of anything to speak of on it, and it worked fine. Very clean install program. I never had a clean VB install in my life.

When it comes to shareware, the install should always be clean.

If you want the experience of a real application, use Delphi. Everything else is just a cludge. I hate it when I download “applications” and they’re nothing more than compiled Access or Filemaker database. No proper by-the-book interface. Of course “real” applications are following suit, too – Windows is getting worse by the day with the sheer quantity of stuff that uses non-standard interfaces – including stuff from Microsoft: why the hell is the default Media Player some crappy “skin” that has no menus. Grrrrr!

Oh, back on topic, I used to like Delphi with an Access back end, but if you can’t count on your users having Access installed, that won’t work for you. That means you can freely install the Delphi database system, but it’s big.

The problem I’ve found with Access runtimes is that they sometimes don’t happily co-exist with other versions of Access (full version or other runtimes) that the user may already have installed. Is the OP in the position to insist that their’s is the only Access installed?

Don’t most DBMS’s on Windows come with an ODBC driver? I Know PostgreSQL does. I would assume, though I have never used it, that VB can use any ODBC data source. I wouldn’t be surprised if Delphi doesn’t also.

On another tack, HSQLDB is a Java based DBMS which can be used with Java through JDBC. It doesn’t even need to be run as a server (though it can be), it can run embedded in your application. Ofcourse writing a Java application may be more work than your requirements can justify. Unfortunatly HSQLDB does not have an ODBC driver.

This will be a small app that I was just doing to help a friend out but I think more people would like to use it.

It’s going to basically be a database with a single user on a PC, that will be used to track music and lyrics to songs. I may also be adding a calendar function so you can see the last time a piece was played.

It doesn’t matter if the user has other Access versions. I just want it relatively easy to develop and easy to install.

I was originally trying to stay away from Access because of it’s size limits. People have LOTS of music to track.

I saw Delphi & Visual FoxPro mentioned, Never worked with them. Steep learning curve? I’m an OK, but not professional, programmer.

If that’s the only reason, then what kind of limits are you talking about? Are there enough songs in existence to top out Access? In any case, I thought you said you were worried people wouldn’t have Access access.

ticker, are you aware of a way to automatically configure an ODBC data source? Because otherwise that would be a bit of an issue for installation. And, if you are, please pass it along because there’s an Access app I want to make but I don’t want to require the user to configure ODBC data sources.

I am worried that people would’nt have access top Access, that would limit it’s usability.

Access db file size maxes out at 1Gb.

Didn’t know that, and I’m a heavy user. :smack:

You could have one Access database for every table, and link them in :wink:

Foxpro can handle plenty of size, (unlike Access), but it’s an 80s language. Very procedural. If you learned programming with tools like VB, VFB may just be too antiquated to be easily learned. Intuitive it is not. Even for a fluent VFB programmer, VB is still much faster for development.

You do not want to store actual mp3s in your database. Rather, you want filenames and some sort of convention/methodology for knowing what folders they are in, (I would not recommend storing any absolute path names. Storing a relative path, however, would be fine.) Also, you want a Memo field for lyrics.

Access is your easiest (and thus best) bet in this regard. Text is (roughly) two bytes per character to store in Access. So, do you really think you’re going to store more than 500,000,000 characters from the lyrics?

One of my Access databases has 30+ megs of text in various Memo fields with no performance issues. I’d be surprised if anyone had more than 50 megs worth of song lyrics associated with mp3s on their hard drive.

I would strongly recommend the following:

  • Use your most comfortable front end language. (Mine would be VB)
  • Start off by using Access as the back end, as you obviously are familiar with it.
  • Create a DataLayer module where all database functions of any kind are stored, and move all other code into other various forms and modules.

Once you are finished in this fastest of all possible development cycles, use the Package & Deployment wizard (or better yet, Wise Installer) to bundle it up and test it out on a machine that doesn’t have Access. It should work without issue.

If you run into some unforseen problems and are forced to abandon Access, all you have to do is modify your data layer. Trust me, when all data access is stripped down and contained in a single module, changing your backend is a breeze.

One technique, if you want to isolate the data layer, is to send custom user data types to functions. Here’s an example basDataLayer.bas module you might start with if you use VB: (Forgive the obsolete DAO method; it’s easier than ADO for these quickie examples)


Option Explicit

Public Type SongInfoType
    Dim lngSongID As Long
    Dim strTitle As String
    Dim strArtist As String
    Dim strLyrics As String
    Dim dtmLastPlayed As Date
    Dim lngPlayCount As Long
End Type

Public Function LoadSong(ByRef psi As SongInfoType)
    Dim db As Database
    Dim rst As Recordset

    Set db = OpenDatabase("Songs.mdb")
    Set rst = db.OpenRecordset("SELECT Title, Artist, Lyrics, LastPlayed, PlayCount FROM tblSongs WHERE SongID = " & psi.lngSongID & ";",dbOpenSnapshot)
    If Not rst.EOF() Then
        psi.strTitle = rst!Title
        psi.strArtist = rst!Artist
        psi.dtmLastPlayed = rst!LastPlayed
        psi.lngPlayCount = rst!PlayCount
    End If
    rst.Close
    Set rst = Nothing
    db.Close
End Function

Public Function SaveSong(ByRef psi As SongInfoType)
    Dim db As Database
    Dim rst As Recordset

    Set db = OpenDatabase("Songs.mdb")
    Set rst = db.OpenRecordset("SELECT SongID, Title, Artist, Lyrics, LastPlayed, PlayCount FROM tblSongs WHERE SongID = " & psi.lngSongID & ";",dbOpenDynaset)
    If psi.lngSongID = 0 Then
        rst.AddNew
    Else
        rst.Edit
    End If
    rst!Title = psi.strTitle
    rst!Artist = psi.strArtist
    rst!LastPlayed = psi.dtmLastPlayed
    rst!PlayCount = psi.lngPlayCount
    rst.Update
    If psi.lngSongID = 0 Then
        rst.Bookmark = rst.LastModified
        psi.lngSongID = rst!SongID
    End If
    rst.Close
    Set rst = Nothing
    db.Close
End Function

Now to save and load your song info, you simply declare a variable of type SongInfoType and pass it to the data layer. Looking at an example, which might be inside a form:


Option Explicit

Sub cmdOpenSong_Click()
    Dim siSong As SongInfoType

    With Me
        siSong.lngSongID = .txtSongSearch.Text
        LoadSongInfo siSong
        .txtTitle.Text = siSong.strTitle
    End With
End Sub

Sub cmdSaveSong_Click()
    Dim siSong As SongInfoType

    With Me
        siSong.lngSongID = .txtSongID.Text
        siSong.strTitle = .txtTitle.Text
        SaveSongInfo siSong
    End With
End Sub

Now this is off the top of my head, and certainly not debugged or anything, but it gives you the basic ideas and concepts. Imagine the entire application is fully developed, and you need to change the data access from, for example, DAO to ADO. Or from Access to (Yikes!) FoxPro. Or to Delphi.

Looking at the data layer, all the functions are going to be pretty straightforward and mindlessly simple to deal with. Nothing else in the app needs to be messed with. This approach lets you use your easiest-to-use backend to get your app up and running, and then once it’s been polished up, you can switch data models on a whim.

One final tip for the data layer strategy: looping through the database. In the data layer:


Public Function SongCount() As Long
    Dim db As Database
    Dim rst As Recordset

    Set db = OpenDatabase("Songs.mdb")
    Set rst = db.OpenRecordset("SELECT Count(SongID) As Songs FROM tblSongs;",dbOpenSnapshot)
    If Not rst.EOF() Then SongCount = rst!Songs
    rst.Close
    Set rst = Nothing
End Function

Public Function GatherSongIDs(pa() As Long)
    Dim db As Database
    Dim rst As Recordset
    Dim i As Long

    Set db = OpenDatabase("Songs.mdb")
    Set rst = db.OpenRecordset("SELECT SongID FROM blSongs;",dbOpenSnapshot)
    i = 0
    Do While Not rst.EOF() 
        i = i + 1
        pa(i) = rst!SongID
        rst.MoveNext
    Loop
    rst.Close
    Set rst = Nothing
End Function

Now if you want to run through all the Songs, you can do it thusly:


Private Function ValidateSongs(ppgb As Progressbar)
    Dim lngMax As Long
    Dim i As Long
    Dim alngSongs() As Long
    Dim siSong As SongInfoType

    lngMax = SongCount()
    Redim alngSongs(1 To lngMax)
    ppgb.Max = lngMax
    ppgb.Visible = True
    For i = 1 To lngMax
        ppgb.Value = i
        LoadSongInfo siSong
        If Dir(siSong.FileSpec) <> "" Then
            Msgbox siSong.Title & " not found on disk.", vbExclamation, "Error"
            Exit For
        End If
    Next
    ppgb.Visible = False
End Function

You can see that once again, even though we’re looping through the table one record at a time and performing an action based on the contents of each record, there is precious little going on in the actual data layer. Certainly nothing complicated, as far as re-writing it for a different back end is concerned.

Let me know if you have any questions. Hope this helps.

PS: I always use a module-level database variables for the actual connection (the db variable, in this case). I’d never keep opening and closing (or forgetting to) the database in every function like I posted in these examples. You always want InitData and CloseData functions in the data layer to open and close your connections, and ideally only call each of them once when your app starts and once when it ends.

I forgot a couple crucial lines in the last function:


Private Function ValidateSongs(ppgb As Progressbar)
    Dim lngMax As Long
    Dim i As Long
    Dim alngSongs() As Long
    Dim siSong As SongInfoType

    lngMax = SongCount()
    Redim alngSongs(1 To lngMax)
    **GatherSongIDs alngSongs**
    ppgb.Max = lngMax
    ppgb.Visible = True
    For i = 1 To lngMax
        ppgb.Value = i
        **siSong.lngSongID = alngSongs(i)**
        LoadSongInfo siSong
        If Dir(siSong.FileSpec) <> "" Then
            Msgbox siSong.Title & " not found on disk.", vbExclamation, "Error"
            Exit For
        End If
    Next
    ppgb.Visible = False
End Function

SQLite is a nice file-based database you can use with desktop apps. I’ve used it in place of Access in VB and C++ apps. I’ve written a lot of little utilities that use VB/Access, and the end user does not have to have Access installed to use them, but I’ve had version issues and other problems with Access that led me to SQLite.

I’ve started using Cloudscape in Java apps for the same purpose and it’s very good.

If you’re set on building a desktop app (as opposed to a client-server app), then pick a language first based on what you have experience in and what solves the problems you have. You could write what you want in about a dozen different languages and there is absolutely no reason to choose one over the other except for personal preference. Don’t let the language zealots tell you differently. Once you’ve picked a language, you can choose among several compatible databases.

erislover: in general, most of these databases allow the application to connect without the user explicitly creating a DSN or other ODBC link. In the case of Access, a VB app can just specify the MDB file to connect to rather than a DSN name. In many cases where an app is linked to a specific database file, you can just put the MDB in the same directory as the EXE and use App.Path to let the VB code find it. The same is basically true of most other solutions.