myIdea Logo

myNotes: Designer's Notes


Note by the author: These are the notes I made mainly for myself. I will not answer any "general audience" questions about these notes and about the technical concepts behind myNotes. If you are a FileMaker developer yourself you are welcome to browse these notes for ideas and concepts, and I am willing to discuss them with anyone who is professionally interested.

Content

Go back to Top


Release History

1.0 (planned version)
Major update
New Features: (none)
Problems found: (none)
0.1 (current version)
Initial version
Problems found: (none)

Go back to Top


Conventions

Field Names

Suffix: Fields carry a suffix that gives information about the field type:

Prefix: Some fields carry a prefix that points to the way they are used:

Go back to Top


Object Types

Tables

Idea
Table Main
basic fields:

Other fields (exemplary selection, not complete):

Set
Table MySets
basic fields:
Category
Table MyCategories
fields: See Set
Status
Table MyStatus
fields: See Set
Icon
Table MyIcons
basic fields:
Person
Table Persons
basic fields:
Organisation
Table Organisations
basic fields:

Go back to Top


Creation of Object Records

The standard procedure to create an object record is:

  1. From a script named Open Dialog *** of the current table (usually Main) initialize the necessary global variables in commonvars. These "global exchange variables" are the same as used for the import functions. The script then pops up a dialog that shows these global fields.
  2. The user edits these fields in this dialog and hits the confirmation button.
  3. The Open Dialog *** script reads the return value and ma yperform some checks. Then it calls the CreateRecord script of the target table.
  4. The CreateRecord script creates a new record and fills in the values provided by the global exchange variables in commonvars. The record Id, CreationDate and CreationTime are filled in automatically by a calculation defined in the field definition.

The advantages of this method are:

Go back to Top


Relations

There are two kinds of relations used in myNotes: 1:n relations and n:m relations.

1:n relations are modelled by an field of the master(source) file that points to the record Id field of thetarget file. Thus, the masetr file can only be related to one record of thetarget file. Example: An Idea can have only 1 Status ata time (but n Ideas can have that Status).
n:m relations imply that each record of the master filecan be related to any number of target records. Example: An Idea can belongto n Sets (and each Set can hold m ideas).Such relations are modelled by the use of

Link Tables
Table names = x_<fromtable>_<totable>.
basic fields:

Info fields (unstored calculations showing values from the related database):

The following link tables are used in myNotes:

An Elegant n:m Assignment Method

The way n:m relations are assigned is described here. Let's assume we wantto assign one or more Person records to an Idearecord.

A Method to Show Only Active Records Without Searching for Them

"Active" equals "not trashed", i.e. it refers to records with an emptyTrashDate field. The same method can obviously be used for anyproblem where a list view is required that shall include only records withcertain field values.

Let us assume we have a table of Persons; this table has a relation thatshows all Ideas (table Main) connected to each Person (tablePersons). The n:m relation is established by the link tablex_Main_Person. If we want to see all Ideas we simplydefine a relation from Person::Id_t tox_Main_Person::ToId_t; all Idea records connected to that Personwill be shown. But what if we only want to see the Ideas that are active,i.e. that do not have a TrashDate set, and if we want to doso without executing a search? Here is the solution:

  1. Add an field Id_fst to Main. It is stored-calculated as
    case( isempty(TrashDate_d); Id_t; "" ), i.e. it equals the Id if no trash date is set.
  2. Add a relation to x_Main_Person. It must be defined to point from x_Main_Person::FromId_t to Main::Id_t. Let's call it "The Idea".
  3. Add an field FromId_lt to x_Main_Person. This is a lookup of Main::Id_fst, using the relation "The Idea" described above.
  4. Add a script to x_Main_Person that performs just Relookup(no Dialog; FromId_t).
  5. Call this (external) script each time you set a TrashDate in Main (this implies that the TrashDate may only be edited by an intermediate dialog and using a script). Do not forget to add a script step to go back to the original layout, or you end up viewing the x_Main_Person table.
  6. Add a stored-calculated field ToId_fst to x_Main_Person. The calulation is
    case( isempty(FromId_lt); ""; ToId_t ), i.e. it is only set if the looked-up value is non-empty, i.e. implicitly it is only set if the TrashDate is empty.
  7. Last step: Add a relation "Active Ideas" to Persons that links Persons::Id_t to x_Main_Person::ToId_fst. Now this relation will show, from the relation table, only those records whose ToId_fst matches the Id_t of the current person. But since ToId_fst depends on the looked-up From_Id_lt, which in turn (if the look-up is current) reflects the value of Main::Id_fst, which in turn is directly dependent on the status of the TrashDate field, it only shows non-trashed records.
    Voila!

Of course this method depends on a re-lookup of the link table fieldFrom_Id_lt each time the viewing condition (in the example,the TrashDate) changes. That is the reason why we must enforcea re-lookup every time TrashDate changes. A recommendation: Switch Allow User Abort(Off) in the script or you may end upwith an incomplete re-lookup with impatient users that use very long tables.

The big advantage over a search is that the result of thisrelation can be directly displayed in a portal, i.e. it is not dependenton the currently found records! Also, you could have two portals side byside of which one shows all records and the other one only the active records,or you could put them on different layouts named something like "Active Ideas"and "All Ideas".

If you need to employ the same principle both ways (as isnecessary in x_Main_Main because we want to see only activerecords for both parents and children) you must also add thecomplementary fields ToId_lt and FromId_fst tox_Main_Main, and use ToId_fst and FromId_fstfor the viewing relations. Also, the re-lookup script in the linktable now needs to do two re-lookups, one for ToId_tand one for FromId_t.

Last remark: Of course you can play on this principle bychanging the calculations in Main::Id_fst andx_Main_Person::ToId_fst, or by simply adding new calculatedId fields to the link table that get their content under different conditions.

Methods Used for Finding Records

Note: "Finding" refers to "finding Idea records". There is no "Find"function for any other object type.

Finding by Field Value

Standard FileMaker "find" operation, no problems here. Searchable fieldsare

A modifier is "include deleted".

Find Ideas by Status or Icon ("Find by 1:n-related item")

This is easy, as it is basically a "Find by Field Value". Pick a Status oran Icon and look for all records that have this StatusId orthis IconId set in their respective fields. Can be implementedas an actual search or by showing a portal with matching Ideas.

Find Ideas by Set, Category, Person or Organisation ("Find by n:m-related item")

This is neccessarily a search on a link table, not in Main.To just show the Ideas in a list is easily implemented by creatinga portal to the link table. To actually create a list of only the found recordsin Main requires a calculated field in Main thatis TRUE if there is a valid reference in the link table and FALSE otherwise.(Note: Since this field will be unstored, it will not be a fastsearch.) The procedure is:

This principle reduces the search in multiple table to a (although slower,because it searches unstored, i.e. non-indexed fields) search in theMain table. So it is possible to use the Category, Set, Personand Organisation associations as search criteria, just like the normal fieldsof the table.

Searching in Found Records (Reducing the "Found" List)

FileMaker cannot directly search the current "found" set, it always searchesall records. If we would just extend the original search, this would implythat we repeat the whole (possible time-consuming) search on all recordswith more search criteria, and this in turn would imply that we store thesearch criteria to re-use them.
Therefore I used a different approach:

  1. A global numeric field LastSearchId_gn is provided in Main.
  2. Each search writes the timestamp of the search into this field after it is complete (using Status(CurrentTime)).
  3. For a subsequent "refined" search, the first action is to write that timestamp into an indexable field LastSearchId_n of Main (a "replace" script step).
  4. Then it does a search for the new criteria AND "LastSearchId_n = LastSearchId_gn". Because LastSearchId_n is indexed, this search is reasonably fast.
  5. Finally, the search writes a new timestamp into LastSearchId_gn.

This principle can be used a couple of times in succession to further reducethe number of found records.

Go back to Top


Auxiliary Tables

commonvars
This table contains global fields that are user-independent, like generally used label texts, colour containers, version numbers , result-, search- and export/import pass-on fields, common value lists etc.
Important fields:
dialog
This table is a generalized dialog panel that is called from other windows when needed. It receives and passes back values via its own global fields. It has a number of layouts that can be used by the calling script.
Important fields:
help
This table contains information for the end-user, among other information a link to the manual.
designinfo
This table contains information about the design elements in the other tables. To be included in the information, the other tables must be referenced by the designinfo table with a link whose first 2 characters are not equal to "__" (double underline). designinfo evaluates the DesignInfo_* fields of the other tables and displays a report.
exportimport
This table is used for import operations. It is an intermediate storage space for imported data and data to export. It makes it possible to view the data before actually importing them into your own files. For details see the section on import/export.
myNotes_export.fp5
This is the file name used for all exports in FileMaker format.
myNotes_export.tab
This is the file name used for all exports in tab-separated text format.
myNotes_backup.fp5
This is the file name used for all user-initiated backups.
myNotes_onstart_backup.fp5
This is the file name used for automatic backups on starting myNotes.
myNotes_onquit_backup.fp5
This is the file name used for automatic backups on quitting myNotes.

Go back to Top


Standard fields

Certain fields are present in all tables:

Id
Id fields must be unique, and are designed to be so. They are always automatically filled in on recored creation.
The standard format for Id fields is
<PersonId_of_DatabaseOwner>|<date_as_integer>|<time_as_integer>
LinkId
The LinkId replaces the standard Id in relation tables. They are stored calculations from the Ids of the linked items (see "Link Tables") in the format <FromId>-<ToId>. They are used for "uniqueness checks", i.e. to prevent duplicate links between the same items.
CreationDate
The date of the record creation, filled automatically by a calculation (commonvars::CurrentDate).
CreationTime
The time of the record creation, filled automatically by a calculation (commonvars::CurrentTime).
(may be omitted in Link tables)
ImportDate
The date this record was imported, filled in at the time of the import. A record with this date set is considered an imported record.
Note: A "restore" from a backup is not an import and does not set this date.
DummyId
Stored calculation, =1, used for "all-to-all" matches between tables, for example to access global fields of the other table or to create a value list of all records of that table.
RecordId
Calculation (usually unstored): The internal ID of the record (Status(CurrentRecordId)).
DesignInfo_*
Unstored calculations, holding data for evaluation by the designinfo table.

Some fields are present in all base tables, but not in linktables:

ModificationDate
The date of the last modification of the record. Uses the FileMaker-internal modification date.
ModificationTime
The time of the last modification of the record. Uses the FileMaker-internal modification time.

Go back to Top


GUI Standards

Text and Image Content Fields
Control-Click = Copy field content to clipboard.
any other Click = Edit content.
Selection Fields
Alt-Click = Edit selected, create new selection item, delete selection item (in sub-dialog).
any other Click = Show possible selections (for example, by showing pop-up list) and choose from them.
Navigation
Blue, underlined texts are navigation links.
Click = jump to target item
Alt-, Shift-, Control- or Command-Click to just show information about the item (without jumping to it).

Go back to Top


Export/Import Procedure

The field order of the export/import file is described in aseparate document.

Export

Each export (except a backup, see below) must be preceded by aFind operation because the export works on the currentlyfound Idea records.

Three types of export are available:

  1. Export to a FileMake file with a pre-defined name; this exports images and icons as well as texts and should be used whenever possible. This format is also used (automatically) for backups.
  2. Export to a tab-separated text file; this does not export images and icons but is identical otherwise. It should only be used if it is necessary to export to an application that cannot read the native FileMaker format.
  3. Free export, i.e. the user is prompted for the file name and type.

Program steps (status bar imforms user of current step):

  1. (if backup) Main: Show all records
    (otherwise) Main: Use found set and confirm with number of records
  2. Main: Sort by CreationDate
  3. Call exportimport script to collect information:
    1. Show and delete all exportimport records.
    2. Create record containing commonvars values.
    3. Import the found set from Main.
    4. Loop through Idea records, on each record:
      1. Import related Status and import (update mode)
      2. Import related Icon and import (update mode)
      3. Import related Parent Idea Links and import (update mode)
      4. Import related Child Idea Links and import (update mode)
      5. Import related Category Links and import (update mode)
      6. Import related Set Links and import (update mode)
      7. Import related Organisation Links and import (update mode)
      8. Import related Person Links and import (update mode)
    5. Find and loop through Idea Link records, on each record:
      1. Check whether both parent and child Idea are present in exportimport, otherwise delete this record
    6. Find, sort by Category Id and loop through Category Link records, on each record:
      1. Note related Category Id
      2. If different from previous Id, import related Category (update mode)
    7. Ditto for Set Link records.
    8. Ditto for Organisation Link records.
    9. Ditto for Person Link records.
    10. Find, sort by Person Id and loop through Person records, on each record:
      1. Import related Person-Organisation Link records (update mode)
    11. Find, sort by Organisation Id and loop through Person-Organisation Link records, on each record:
      1. If not yet present in exportimport, import related Organisation (update mode)
  4. Call exportimport script for actual export to file.
  5. After an export or backup with fixed filename: Show message that the file should be re-named immediately or it will be overwritten by the next export.

Import

The import is a two-step process. First the data is read into the tableexportimport. There you can view it and possibly delete recordsyou do not need. Then, the data is imported into the several tables.

Program steps for loading the data:

Now the data is displayed in a portal (sorted by ObjectType).The portal shows whether a corresponding record exists, and shows the differencesbetween them on demand.
The user can now view the records and delete any he does not need. When heis done, he clicks the "Import to Database" button.

Program steps for importing the data:

  1. exportimport script: Show all records.
  2. Read the commonvars fields, note ExportDate, ExportTime and (export-) DatabaseOwner in commonglobals.
  3. On Restore only: Check (export-) DatabaseOwner against current DatabaseOwner; if they match, or if the current DatabaseOwner is empty, restore commonvars fields, otherwise throw message and abort.
  4. Run imports (all in update mode, all via import script in target table):
    1. Main: Import all Idea records (update mode)
    2. MyStatus: Import all Status records (update mode)
    3. MyIcons: Import all Icon records (update mode)
    4. MySets: Import all Set records (update mode)
    5. MyCategories: Import all Category records (update mode)
    6. Persons: Import all Person records (update mode)
    7. Organisations: Import all Organisation records (update mode)
    8. All Link tables: Import all Link records (update mode)
  5. Clear all records from exportimport.

Backup/Restore

A backup is identical to the "export to FileMaker format", but it is donefor all records. The one difference during export is that the normal exportdoes not contain the DatabaseKey while the backup copy does.The restore works identical to the import with the exception that a restorealso restores the data from the commonvars fields while thenormal import does not.

The Backup/Restore method is meant to be used mainly for the transfer ofdata to updated versions of myNotes. Of course, the fastest backup methodfor daily use is to copy the complete myNotes folder.

Go back to Top


License Key Management

User licenses are based on a match between DatabaseOwner andDatabaseKey (plus, possibly, the ProgramVersion,all of which are global variables in commonvars). The key stringis generated by the distributor from the DatabaseOwner string(and possibly the ProgramVersion string). When the key stringis entered by the user it is checked against the DatabaseOwner(and possibly ProgramVersion) of the current database, usingthe same generation algorithm. Only if it is accepted it is written intothe DatabaseKey field.

A database with an empty DatabaseKey field runs in demomode. The limitations of demo mode are:

Go back to Top


Half-Baked Concept Notes

xxxxxxxxxx

Go back to Top


To Do List

Report Generator
print one idea
print all ideas in set
print all ideas of one category
General Functions
Implement licensing system
Implement export (including "backup on start" and "backup on quit")
Implement Find
Implement X-Link
Implement Admin
add "backup on start" and "backup on quit"
add print "watermark" for unlicensed version
commonvars
add name strings for ObjectTypes in exportimport
main
remove comments from check_key script
complete Person-, Set-, Org-, Category-Association panels
clean up person edit panel
main: Find
function "make set from found records"
function "add found records to set"
main: Admin
function "copy person" (including Org links)
documentation
(big heap of work yet!)

Go back to Top


This page is part of the documentation for the myNotes software. It is copyrighted by the author of the program according to the copyright note.
Program version: 0.1 , Documentation version: 1.12.2004
All rights reserved. Lutz Pietschker, Berlin/Germany, 2008 ff.

, last change 2013-03-18