User Tools

Site Tools


k6:k6.1:k6.1.3:start

6.1.3 Project

After the explanations in the last two chapters, you will be introduced to the project PathProject, which creates the executable file PathProject.gambas as a Gambas archive. The programme was designed and tested for the following three scenarios under the aspect of 'working with paths in Gambas':

1. start in the IDE (F5 or via the button in the toolbar with the ► symbol).
2. start in the project directory with
2.1 $ gbx3 $HOME/GB3BOOK/6K_Stream/6.1_Paths/BookProgram/PathProject
or
2.2 $ gbr3 $HOME/GB3BOOK/6K_Stream/6.1_Paths/BookProgram/PathProject/PathProject.gambas
3. start on the desktop with hans@mint-183 ~/Desk $ ./PathProject.gambas, if for example only the Gambas archive was copied to the desktop.

The project implements a simple database client. A SQLite3 database with a table (file contacts.s3db) and further files (help file, script file, sound files and image files) are provided in special directories in the project directory or created there. The database table can be read and changed.

|~/GB3BUCH/6K_Stream/6.1_Pfade/BuchProgramm/PathProject
├── data
│   ├── databases
│   │   ├── contacts_original.s3db
│   │   └── contacts.s3db
│   ├── texts
│   └── xml
├── help
│   └── help.txt
├── leds
│   ├── gray16.png
│   ├── green16.png
│   └── red16.png
├── scripts
│   └── dump.sh
├── sounds
│   ├── sound_e.wav
│   ├── sound_s.wav
│   └── start.ogg
└── symbols
    ├── db32.png
    ├── form_icon.png
    ├── logo3.png
    └── project_icon.png

Initial considerations with regard to working with files are also generally applied in this project to the answers to questions such as these:

  • Are configuration files needed?
  • Which files are read-only ®? Paths?
  • Which files need to be read and written to (rw)?
  • Are scripts, NamedPipes or (local) Unix sockets used?
  • Do files require the right to execute?
  • Are files required that are only created temporarily at runtime (save intermediate results, scripts, NamedPipes, (local) Unix sockets)?
  • Do relevant data - stored in files - need to be available even after a system restart?

In case you need to copy files to a suitable directory in the system temporarily or permanently, you should follow the following general suggestions and recommendations.

Configuration file:
For configuration files, consistently use the gb.settings component. Do not use the default path as the path for the configuration file. In this case, set ~/Desktop.ConfigDir/… as the base directory. as the base directory. In the case of a CSS file, for example, you must decide whether it is to be regarded as a configuration file or as a data file.

Data file:
If data must be available (permanently) even after a system restart, then these data files belong in the basic directory ~/Desktop.DataDir/… . Data that is generated and stored as intermediate results at runtime should be stored in temporary files either in /tmp/… or ~/Desktop.RuntimeDir/… . After /tmp/… or ~/Desktop.RuntimeDir/… also belong NamedPipes and local UnixSockets, because they are bound to the runtime of the Gambas process.

Database (DB):
A database or its DB tables only need to be read if you only want to display its records. If changes to the DB tables are permitted, the database and its tables must be readable and writable by the user. Note: After creation, an SQLite3 database automatically has only the rights: rw-r–r– .

Script file:
Scripts “*.{sh,sql,pl,py,gbs,…}” must be able to be read and executed. Since the shell and exec instructions require absolute paths, you must copy the scripts to a suitable directory in the system and make them executable with CHMOD path2script TO permission_string. Since shell scripts are only used temporarily, they belong in /tmp/… or ~/Desktop.RuntimeDir/… .

It has been specified that the shell script dump.sh is only used temporarily and is therefore copied to the directory /run/user/user-id/gambasbook/pathproject/scripts.

Sound file:
A sound file must only be read. However, if you give the user the chance to replace the sound files - under the old file names - then you must copy the sound files into a suitable base directory such as ~/Desktop.DataDir/… permanently.

Image file:
If you need a special icon for each of certain controls, then these only need to be read.

Help file:

A help file must normally be read only. However, the user may be interested in modifying the help file outside the programme, for example to insert a translation in another language.If there is no such interest, then it remains hidden in the project files - otherwise it must be copied permanently to a suitable basic directory such as ~/Desktop.DataDir/…. permanently.

In the following table you can see an overview of the intended paths of special directories:

FilesTypeRwxDirectory path
image-files1localrproject-directory/leds
image-files2localrproject directory/symbols
Help files localrProject directory/help
Sound fileslocalrProject directory/sounds
Script files local-Project directory/scripts
Data fileslocal-Project directory/data
Databaseslocal-Project directory/data/database
Data filesglobalrw~/.local/share/gambasbook/pathproject/data
Databaseglobalrw~/.local/share/gambasbook/pathproject/data/database
Sound filesglobalr~/.local/share/gambasbook/pathproject/sounds
Script filesglobalrx/run/user/user-id/gambasbook/pathproject/scripts (temporary)
configuration filesglobalrw~/.config/gambasbook/pathproject

Table 6.1.3.1 : Overview of the used (base) directories

The combination of provider-name/project-name as gambasbook/pathproject consistently serves as NameSpace. Note that both the vendor name (Vendor) - often it is the name of the developer - and the name of the application have been hard coded in the two variables sVendor and sAppName. The reason for the project name is that you cannot safely use the Application.Name property, which was discussed in the previous chapter. You could read out the name of the vendor from the (hidden) file .project - but this presupposes that this name has been entered in the project properties. If this is not the case, then it is set:

If Exist(".../.project") Then
   For Each sRow In Split(File.Load(".../.project"), gb.NewLine)
     If sRow Begins "Vendor" Then
        sVendor = Scan(sRow, "*=*")[1]
     Endif
   Next
Endif
If Not sVendor Then sVendor = "gambasbook" ' The vendor for all projects of the author is `gambasbook`.


Figure 6.1.3.1: 'Paths in Gambas' demonstration programme

The source code for the class FMain.class for the project `PathProject` is given in full. All other classes and modules can be found in the download directory in the project archive.

' Gambas class file
 
' SQLite has no concept of users. Access to a database is controlled by the actual file permissions
' of the database file. This means that the Login is always the user id executing the Gambas program.
 
Public cC As Component
 
Public sTempDir As String
'----------------------------------
Public sGlobalConfigDir As String
Public sGlobalRuntimeDir As String
Public sGlobalDataDir As String
Public sGlobalDBHostDir As String
Public sGlobalScriptsDir As String
Public sGlobalSoundsDir As String
'----------------------------------
Public sLocalDataDir As String
Public sLocalDBHostDir As String
Public sLocalHelpDir As String
Public sLocalLEDsDir As String
Public sLocalScriptsDir As String
Public sLocalSoundsDir As String
Public sLocalSymbolsDir As String
'----------------------------------
Public sVendor As String
Public sAppName As String
Public sDBName As String
Public sFile As String
Public hSettings As Settings
Public sMessage As String
Public sDBTableName As String
 
Public Sub _new()
 
  Dim sRow As String
 
  If Exist(".../.project") Then
     For Each sRow In Split(File.Load(".../.project"), gb.NewLine)
       If sRow Begins "Vendor" Then
          sVendor = Scan(sRow, "*=*")[1]
       Endif
     Next
  Endif
  If Not sVendor Then sVendor = "gambasbook"
 
  sAppName = "PathProject"
  sDBName = "contacts.s3db"
  sDBTableName = "contacts"
'------------------------------
  sLocalDataDir = "data"
  sLocalDBHostDir = "databases"
  sLocalHelpDir = "help"
  sLocalLEDsDir = "leds"
  sLocalScriptsDir = "scripts"
  sLocalSoundsDir = "sounds"
  sLocalSymbolsDir = "symbols"
'------------------------------------------------------------------------------------------------
  sGlobalConfigDir = Desktop.ConfigDir &/ sVendor &/ Lower(sAppName)
  If Not Exist(sGlobalConfigDir) Then Shell.MkDir(sGlobalConfigDir)
'------------------------------------------------------------------------------------------------
  sGlobalRuntimeDir = Desktop.RuntimeDir &/ sVendor &/ Lower(sAppName)
  If Not Exist(sGlobalRuntimeDir) Then Shell.MkDir(sGlobalRuntimeDir)
'------------------------------------------------------------------------------------------------
  sGlobalDataDir = Desktop.DataDir &/ sVendor &/ Lower(sAppName) &/ GetDirPath(sLocalDataDir)
  If Not Exist(sGlobalDataDir) Then Shell.MkDir(sGlobalDataDir)
'------------------------------------------------------------------------------------------------
  sGlobalDBHostDir = sGlobalDataDir &/ sLocalDBHostDir
  If Not Exist(sGlobalDBHostDir) Then Shell.MkDir(sGlobalDBHostDir)
  For Each sFile In Dir(sLocalDataDir &/ sLocalDBHostDir, "*.s3db")
    If Not Exist(sGlobalDBHostDir &/ sFile) Then
       Copy sLocalDataDir &/ sLocalDBHostDir &/ sFile To sGlobalDBHostDir &/ sFile
    Endif
  Next
'------------------------------------------------------------------------------------------------
  sGlobalScriptsDir = sGlobalRuntimeDir &/ GetDirPath(sLocalScriptsDir)
  If Not Exist(sGlobalScriptsDir) Then
     Shell.MkDir(sGlobalScriptsDir)
  Endif
  For Each sFile In Dir(sLocalScriptsDir, "*.{sh,sql,pl,py,gbs}")
    If Not Exist(sGlobalScriptsDir &/ sFile) Then
       Copy sLocalScriptsDir &/ sFile To sGlobalScriptsDir &/ sFile
       Chmod sGlobalScriptsDir &/ sFile To "..x......"
    Endif
  Next
'------------------------------------------------------------------------------------------------
  sGlobalSoundsDir = Desktop.DataDir &/ sVendor &/ Lower(sAppName) &/ GetDirPath(sLocalSoundsDir)
  If Not Exist(sGlobalSoundsDir) Then
     Shell.MkDir(sGlobalSoundsDir)
  Endif
  For Each sFile In Dir(sLocalSoundsDir, "*.{ogg,wav}")
    If Not Exist(sGlobalSoundsDir &/ sFile) Then
       Copy sLocalSoundsDir &/ sFile To sGlobalSoundsDir &/ sFile
    Endif
  Next
'------------------------------------------------------------------------------------------------
 
  hSettings = New Settings(sGlobalConfigDir &/ File.SetExt(Lower(sAppName), "conf"))
  SetNotification("dialog-information", "Attention!")
 
End
 
Public Sub Form_Open()
 
  Dim i As Integer
 
  If Not System.Exist("sqlite3") Then
     sMessage = "<b><font size='+1', color='DarkRed'>"
     sMessage &= "The application requires the program 'sqlite3'."
     sMessage &= "</b></font><hr>"
     sMessage &= "Installation console (MINT): $ sudo apt-get install sqlite3"
     sMessage &= "\nThe application is therefore terminated!"
     MAddOns.PlaySound(sGlobalSoundsDir &/ "sound1.ogg")
     Message.Info(sMessage)
     Quit
  Else
   ' Message.Info("The programm path from 'sqlite3' is: " & System.Find("sqlite3"))
  Endif
 
' The 'About ...' window is displayed exactly twice.
  If hSettings["First/Value", 0] < 2 Then
     i = hSettings["First/Value", 0]
     Inc i
     hSettings["First/Value"] = i
     hSettings.Save()
     FAbout.ShowModal()
  Endif
 
  DataSource1.Connection = DBCS.DBConnection
  sGlobalDBHostDir = DBCS.DBConnection.Host
  DataSource1.Table = sDBTableName
 
  SetDBBrowserProperties()
  SetDataControlProperties()
 
  btnShowDumpData.Enabled = False
 
  pboxOnOff.Picture = Picture.Load(".../leds/green16.png")
' pboxOnOff.Picture = Picture["leds/green16.png"] ' Alternative
 
  FMain.Icon = Picture[sLocalSymbolsDir &/ "project_icon.png"]
 
End
 
Public Sub btnDBSicherungDumpE_Click()
  btnShowDumpData.Enabled = True
  MAddOns.PlaySound(sGlobalSoundsDir &/ "sound_e.wav")
  pboxOnOff.Picture = Picture["leds/red16.png"]
  GetDBDumpExec()
  Wait 0.2
  pboxOnOff.Picture = Picture["leds/green16.png"]
End
 
Public Sub btnDBSicherungDumpS_Click()
  btnShowDumpData.Enabled = True
  MAddOns.PlaySound(sGlobalSoundsDir &/ "sound_s.wav")
  pboxOnOff.Picture = Picture.Load(".../leds/red16.png")
  GetDBDumpShell()
  Wait 0.2
  pboxOnOff.Picture = Picture.Load(".../leds/green16.png")
End
 
Public Sub btnHelp_Click()
  FHelp.ShowModal()
End
 
Public Sub btnShowDumpData_Click()
  FShowDump.ShowModal()
  btnShowDumpData.Enabled = False
End
 
Public Sub btnHelpLibrary_Click()
 
  Dim cl As Class
 
  cC = Component.Load(":gambasbook/LPathProject:1.2")
  cl = Class.Load("Module1")
  Object.Call(cl, cl.Symbols[0], Zero)
  Catch
  Message.Error(Error.Text)
 
End
 
Private Sub SetDBBrowserProperties()
  DataBrowser1.Labels = ["ID", "First name", "Surname", "Postcode", "Residence", "Street", "E-mail address"]
  DataBrowser1.CanCreate = True
  DataBrowser1.CanDelete = True
  DataBrowser1.Editable = False
  DataBrowser1.View.Clear()
  DataBrowser1.Columns = ["id", "first name", "surname", "postcode", "residence", "street", "e-mail address"]
  DataBrowser1.View.Columns[0].Width = 30
  DataBrowser1.View.Columns[1].Width = 90
  DataBrowser1.View.Columns[2].Width = 90
  DataBrowser1.View.Columns[3].Width = 45
  DataBrowser1.View.Columns[4].Width = 120
  DataBrowser1.View.Columns[5].Width = 125
  DataBrowser1.View.Columns[6].Width = 1
  DataBrowser1.View.MoveTo(0, 0) ' … necessary!
End
 
Private Sub SetDataControlProperties()
  dcVorname.Field = "first name"  ' Data control - DB fields are data-sensitive!
  dcNachname.Field = "surname"
  dcPLZ.Field = "postcode"
  cdWohnort.Field = "residence"
  dcStrasse.Field = "street"
  dcEMailAdresse.Field = "e-mail"
End
 
Private Sub GetDBDumpShell()
 
  Dim sShellCommand, sParameter1, sParameter2 As String
 
' The file extension .sql is automatically supplemented with the Dump command!
' The quotation marks prevent the interpretation of the blanks as a tax mark.
  sParameter1 = Shell$(sGlobalDBHostDir &/ sDBName)
  sParameter2 = Shell$(sGlobalDBHostDir &/ "dump." & sDBTableName)
  sShellCommand = Subst$("sqlite3 &1 .dump .quit > &2.sql", sParameter1, sParameter2)
  Shell sShellCommand Wait
End
 
Private Sub GetDBDumpExec()
 
  Dim aExecCommand As String[]
  Dim sTempScriptPath, sLocalScriptPath As String
 
  sLocalScriptPath = sLocalScriptsDir &/ "dump.sh"
  sTempScriptPath = Temp(File.BaseName(sLocalScriptPath)) & ".sh" ' Absolute path!
 
' The query is necessary because an existing file is not overwritten.
  If Not Exist(sTempScriptPath) Then Copy sLocalScriptPath To sTempScriptPath
' Chmod sTempScriptPath To "rwxr--r--"  ' All rights are *explicitly* set anew!
' Only the "Execute" permission is set for the owner - all others are retained.
  Chmod sTempScriptPath To "..x......"
 
' The file extension .sql is automatically supplemented with the Dump command!
  aExecCommand = [sTempScriptPath, sGlobalDBHostDir &/ sDBName, sGlobalDBHostDir &/ "dump." & sDBTableName]
  Exec aExecCommand Wait
End
 
Private Function GetDirPath(sDir As String) As String
  If sDir Not Begins "." Then
     Return sDir
  Else
     Return Scan(sDir, "*/*")[1]
  Endif
End
 
Private Sub SetNotification(Icon As String, BaseText As String)
 
  Dim sNotificationIcon, sNotificationBaseText, sNotificationText As String
 
  sNotificationIcon = Icon ' Options: "dialog-information" or "dialog-warning"
  sNotificationBaseText = BaseText ' For example: "Attention!"
  sNotificationText = ("The program demonstrates the use of file paths in Gambas.")
 
  MAddOns.SendNotification(sNotificationIcon, sNotificationBaseText, sNotificationText, -1)
  MAddOns.PlaySound(sGlobalSoundsDir &/ "start.ogg")
 
End
 
Public Sub btnClose_Click()
  If DBCS.DBConnection.Opened Then DBCS.DBConnection.Close()
  FMain.Close()
End
 
Public Sub Form_Close()
  DBCS.DBConnection.Close()
End

Download

Projects

Download

The website uses a temporary session cookie. This technically necessary cookie is deleted when the browser is closed. You can find information on cookies in our privacy policy.
k6/k6.1/k6.1.3/start.txt · Last modified: 30.01.2022 (external edit)

Page Tools