SDFileSystemSampleCode3

Sample Code 3 - Database example (multiple files, FSeek, GetRecord, SetRecord and Truncate)

Device = 18F4620
Clock =  40
Config OSC = HSPLL

#option SD_SPI = MSSP
#option SD_SPI_SPEED = spiOscDiv4
#option SD_SUPPORT_SUB_DIRECTORIES = True
#option SD_SUPPORT_MULTIPLE_FILES = True
#option SD_MAX_FILES = 2
Include "Convert.bas"
Include "USART.bas"
Include "SDFileSystem.bas"
Include "String.bas"

Const
   dbCourses = 0,
   dbPlayers = 1

Structure THole
   Yards As Word
   Par As Byte
   StrokeIndex As Byte
End Structure

Structure TCourse
   Index As Byte
   Name As String(20)
   Hole(3) As THole
End Structure

Structure TPlayer
   Index As Byte
   Name As String(30)
   Handicap As Byte
End Structure

Dim USARTResponse As String(2)

{
********************************************************************************
* Name    : InputCourse                                                        *
********************************************************************************
}   
Sub InputCourse()
Dim Course As TCourse
Dim HoleNumber As Byte
Dim StringEntry As String(20)
   Course.Index = SD.NumberOfRecords(dbCourses)
   USART.Write("Enter Course Name:", 13, 10)
   USART.Read(StringEntry)
   Course.Name = StringEntry
   For HoleNumber = 0 To 2
      USART.Write("Enter Yards for Hole ", DecToStr(HoleNumber + 1), ":", 13, 10)
      USART.Read(StringEntry)
      Course.Hole(HoleNumber).Yards = StrToDec(StringEntry)
   Next
   For HoleNumber = 0 To 2
      USART.Write("Enter Par for Hole ", DecToStr(HoleNumber + 1), ":", 13, 10)
      USART.Read(StringEntry)
      Course.Hole(HoleNumber).Par = StrToDec(StringEntry)
   Next
   For HoleNumber = 0 To 2
      USART.Write("Enter Stroke Index for Hole ", DecToStr(HoleNumber + 1), ":", 13, 10)
      USART.Read(StringEntry)
      Course.Hole(HoleNumber).StrokeIndex = StrToDec(StringEntry)
   Next
   SD.NewRecord(dbCourses, AddressOf(Course))
   SD.SaveFile(dbCourses)
   USART.Write(13, 10)
End Sub
{
********************************************************************************
* Name    : InputPlayer                                                        *
********************************************************************************
}   
Sub InputPlayer()
Dim Player As TPlayer
Dim StringEntry As String(30)
   Player.Index = SD.NumberOfRecords(dbPlayers)
   USART.Write("Enter Player Name:", 13, 10)
   USART.Read(StringEntry)
   Player.Name = StringEntry
   USART.Write("Enter Player Handicap:", 13, 10)
   USART.Read(StringEntry)
   Player.Handicap = StrToDec(StringEntry)
   SD.NewRecord(dbPlayers, AddressOf(Player))
   SD.SaveFile(dbPlayers)
   USART.Write(13, 10)
End Sub
{
********************************************************************************
* Name    : DeleteCourse                                                       *
********************************************************************************
}   
Sub DeleteCourse()
Dim Course As TCourse
Dim CourseNumber As Byte
Dim StringEntry As String(20)
Dim Found As Boolean
   USART.Write("Enter Course to Delete:", 13, 10)
   USART.Read(StringEntry)
   CourseNumber = 0
   Found = False
   If SD.NumberOfRecords(dbCourses) > 0 Then
      Repeat
         SD.GetRecord(dbCourses, CourseNumber, AddressOf(Course))
         If Course.Name = StringEntry Then
            Found = True
         Else
            Inc(CourseNumber)
         EndIf
      Until CourseNumber = SD.NumberOfRecords(dbCourses) Or Found
      If Found Then                     // Move last record into record to be deleted                         
         SD.GetRecord(dbCourses, SD.NumberOfRecords(dbCourses) - 1, AddressOf(Course))
         SD.SetRecord(dbCourses, CourseNumber, AddressOf(Course))
         SD.FSeek(dbCourses, SD.FileSize(dbCourses) - SD.RecordLength(dbCourses))
         SD.Truncate(dbCourses)
         SD.SaveFile(dbCourses)
         USART.Write("Course Deleted:", 13, 10, 13, 10)
      EndIf
   EndIf
End Sub
{
********************************************************************************
* Name    : DeletePlayer                                                       *
********************************************************************************
}   
Sub DeletePlayer()
Dim Player As TPlayer
Dim PlayerNumber As Byte
Dim StringEntry As String(30)
Dim Found As Boolean
   USART.Write("Enter Player to Delete:", 13, 10)
   USART.Read(StringEntry)
   PlayerNumber = 0
   Found = False
   If SD.NumberOfRecords(dbPlayers) > 0 Then
      Repeat
         SD.GetRecord(dbPlayers, PlayerNumber, AddressOf(Player))
         If Player.Name = StringEntry Then
            Found = True
         Else
            Inc(PlayerNumber)
         EndIf
      Until PlayerNumber = SD.NumberOfRecords(dbPlayers) Or Found
      If Found Then                     // Move last record into record to be deleted                         
         SD.GetRecord(dbPlayers, SD.NumberOfRecords(dbPlayers) - 1, AddressOf(Player))
         SD.SetRecord(dbPlayers, PlayerNumber, AddressOf(Player))
         SD.FSeek(dbPlayers, SD.FileSize(dbPlayers) - SD.RecordLength(dbPlayers))
         SD.Truncate(dbPlayers)
         SD.SaveFile(dbPlayers)
         USART.Write("Player Deleted:", 13, 10, 13, 10)
      EndIf
   EndIf
End Sub
{
********************************************************************************
* Name    : OutputCourses                                                      *
********************************************************************************
}   
Sub OutputCourses()
Dim Course As TCourse
Dim CourseNumber As Byte
Dim HoleNumber As Byte
   If SD.NumberOfRecords(dbCourses) > 0 Then
      For CourseNumber = 0 To SD.NumberOfRecords(dbCourses) - 1
         SD.GetRecord(dbCourses, CourseNumber, AddressOf(Course))
         USART.Write("Course Index: ", DecToStr(Course.Index), 13, 10)
         USART.Write("Name: ", Course.Name, 13, 10)
         For HoleNumber = 0 To 2
            USART.Write("Hole: ", DecToStr(HoleNumber + 1),
                        ", Yards: ", DecToStr(Course.Hole(HoleNumber).Yards),
                        ", Par: ", DecToStr(Course.Hole(HoleNumber).Par),
                        ", StrokeIndex: ", DecToStr(Course.Hole(HoleNumber).StrokeIndex), 13, 10)
         Next
         USART.Write(13, 10)
      Next
   EndIf
End Sub
{
********************************************************************************
* Name    : OutputPlayers                                                      *
********************************************************************************
}   
Sub OutputPlayers()
Dim Player As TPlayer
Dim PlayerNumber As Byte
   If SD.NumberOfRecords(dbPlayers) > 0 Then
      For PlayerNumber = 0 To SD.NumberOfRecords(dbPlayers) - 1
         SD.GetRecord(dbPlayers, PlayerNumber, AddressOf(Player))
         USART.Write("Player Index: ", DecToStr(Player.Index), 13, 10)
         USART.Write("Name: ", Player.Name, 13, 10)
         USART.Write("Handicap: ", DecToStr(Player.Handicap), 13, 10)
         USART.Write(13, 10)
      Next
   EndIf
End Sub
{
********************************************************************************
* Name    : SortCourses                                                        *
********************************************************************************
}   
Sub SortCourses()
Dim Course1, Course2 As TCourse
Dim CourseNumber As Byte
Dim SortOccurred As Boolean
   If SD.NumberOfRecords(dbCourses) > 1 Then
      Repeat
         SortOccurred = False
         For CourseNumber = 0 To SD.NumberOfRecords(dbCourses) - 2
            SD.GetRecord(dbCourses, CourseNumber, AddressOf(Course1))
            SD.GetRecord(dbCourses, CourseNumber + 1, AddressOf(Course2))
            If Str.Compare(Course1.Name, Course2.Name) > 0 Then
               SD.SetRecord(dbCourses, CourseNumber, AddressOf(Course2))
               SD.SetRecord(dbCourses, CourseNumber + 1, AddressOf(Course1))
               SortOccurred = True
            EndIf
         Next      
      Until Not SortOccurred
   EndIf
   SD.SaveFile(dbCourses)
   USART.Write("Courses Sorted:", 13, 10, 13, 10)
End Sub
{
********************************************************************************
* Name    : SortPlayers                                                        *
********************************************************************************
}   
Sub SortPlayers()
Dim Player1, Player2 As TPlayer
Dim PlayerNumber As Byte
Dim SortOccurred As Boolean
   If SD.NumberOfRecords(dbPlayers) > 1 Then
      Repeat
         SortOccurred = False
         For PlayerNumber = 0 To SD.NumberOfRecords(dbPlayers) - 2
            SD.GetRecord(dbPlayers, PlayerNumber, AddressOf(Player1))
            SD.GetRecord(dbPlayers, PlayerNumber + 1, AddressOf(Player2))
            If Str.Compare(Player1.Name, Player2.Name) > 0 Then
               SD.SetRecord(dbPlayers, PlayerNumber, AddressOf(Player2))
               SD.SetRecord(dbPlayers, PlayerNumber + 1, AddressOf(Player1))
               SortOccurred = True
            EndIf
         Next      
      Until Not SortOccurred
   EndIf
   SD.SaveFile(dbPlayers)
   USART.Write("Players Sorted:", 13, 10, 13, 10)
End Sub


// Program start...
USART.SetBaudrate(br115200)
USART.ReadTerminator = #13
DelayMS(100)

USART.Write("Insert SD/MMC:", 13, 10)
Repeat
Until SD.Init() = errOK

If Not SD.FileExists("COURSES.SDB") Then
   USART.Write("New DB: COURSES", 13, 10)
   SD.NewFile(dbCourses, "COURSES.SDB")
   SD.CloseFile(dbCourses)
EndIf

If Not SD.FileExists("PLAYERS.SDB") Then
   USART.Write("New DB: PLAYERS", 13, 10)
   SD.NewFile(dbPlayers, "PLAYERS.SDB")
   SD.CloseFile(dbPlayers)
EndIf

SD.OpenFileRW(dbCourses, "COURSES.SDB", 33)
SD.OpenFileRW(dbPlayers, "PLAYERS.SDB", 32)

Repeat
   USART.Write("Enter Menu Option:", 13, 10,
               "1: Add course  2: Display all courses  3: Sort courses  4: Delete course", 13, 10,
               "5: Add player  6: Display all players  7: Sort players  8: Delete player  9: Exit", 13, 10,
               13, 10)
   USART.Read(USARTResponse)
   Select USARTResponse
      Case "1" InputCourse()
      Case "2" OutputCourses()
      Case "3" SortCourses()
      Case "4" DeleteCourse()
      Case "5" InputPlayer()
      Case "6" OutputPlayers()
      Case "7" SortPlayers()
      Case "8" DeletePlayer()
      Case "9" Break
   EndSelect
Until False

SD.CloseAll

USART.Write("Completed:", 13, 10)
DelayMS(1000)
End