Categorygithub.com/amanbolat/gofmcon
modulepackage
1.0.4
Repository: https://github.com/amanbolat/gofmcon.git
Documentation: pkg.go.dev

# README

Go Report Card

About

This library provides access to FileMaker Server using XML Web publishing.

Initially the library was a port of https://github.com/PerfectlySoft/Perfect-FileMaker, but it evolved a lot since.

In Production

The library is used in production to proxy the calls from API server to FileMaker database.

Tests

FileMaker differs Postgres or MySQL, so we cannot run docker and test the library in CI/CD. Maybe we could run EC2 with Windows and install FileMaker Server on it to run the integration test, yet it seems a bit overkill and very time-consuming at this moment.

Installation

Run the command below in the root directory of your project:

go get github.com/amanbolat/gofmcon

Then import the lib in your code:

import "github.com/amanbolat/gofmcon"

Examples

Full example

package main

import (
	"encoding/json"
	fm "github.com/amanbolat/gofmcon"
	"log"
	"github.com/kelseyhightower/envconfig"
	"fmt"
	"errors"
)

// config represents all the configuration we need in order to
// create a new FMConnector and establish the connection with 
// FileMaker database 
type config struct {
	FmHost         string `split_words:"true" required:"true"`
	FmUser         string `split_words:"true" required:"true"`
	FmPort         string `split_words:"true" required:"true"`
	FmDatabaseName string `split_words:"true" required:"true"`
	FmPass         string `split_words:"true" required:"true"`
}

type postStore struct {
	fmConn *fm.FMConnector
	dbName string
}

type Post struct {
	Author  string `json:"Author"`
	Title   string `json:"Title"`
	Content string `json:"Content"`
}

func (p *Post) Populate(record *fm.Record) {
	p.Author = record.Field("author")
	p.Title = record.Field("title")
	p.Content = record.Field("content")
}

func main() {
	var conf = &config{}
	err := envconfig.Process("", conf)
	if err != nil {
		log.Fatal(err)
	}

	fmConn := fm.NewFMConnector(conf.FmHost, conf.FmPort, conf.FmUser, conf.FmPass)
	store := postStore{fmConn: fmConn, dbName: conf.FmDatabaseName}

	posts, err := store.GetAllPosts(fmConn)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Print(posts)
}

func (ps *postStore) GetAllPosts() ([]Post, error) {
	var posts []Post

	q := fm.NewFMQuery(ps.dbName, "posts_list_layout", fm.FindAll)
	fmset, err := ps.fmConn.Query(q)
	if err != nil {
		return posts, errors.New("failed to get posts")
	}

	// Populate it with record
	for _, r := range fmset.Resultset.Records {
		p := Post{}

		b, _ := r.JsonFields()
		_ = json.Unmarshal(b, &p)
		posts = append(posts, p)
	}

	return posts, nil
}

Get a single record

    q := fm.NewFMQuery(databaseName, layout_name, fm.Find)
    q.WithFields(
        fm.FMQueryField{Name: "field_name", Value: "001", Op: fm.Equal},
    ).Max(1)

Check if the error is FileMaker specific one

    fmSet, err := fmConn.Query(q)
    if err != nil {
        if err.Error() == fmt.Sprintf("FileMaker_error: %s", fm.FileMakerErrorCodes[401]) {
            // your code
        }
    
        // else do something
    }

Create a record

    q := fm.NewFMQuery(databaseName, layout_name, fm.New)
    q.WithFields(
        fm.FMQueryField{Name: "field_name", Value: "some_value"},
    )
    
    fmSet, err := fmConn.Query(q)

Sort the records

    q.WithSortFields(fm.FMSortField{Name: "some_field", Order: fm.Descending})

Update a record

Your object should have FileMaker record id to update record in database. Please see more in FileMaker documentation.

    q := fm.NewFMQuery(databaseName, layout_name, fm.Edit)
    q.WithFields(
        fm.FMQueryField{Name: "field_name", Value: "some_new_value"},
    )
    q.WithRecordId(updated_object.FMRecordID)

Run a script

    // SCRIPT_DELIMITER can be '|', '_' or any other symbol that will be
    // parsed on FileMaker side to get all the parameters from the string
    q.WithPostFindScripts(SCRIPT_NAME, strings.Join([]string{param_1, param_2, param_3}, SCRIPT_DELIMITER))

# Functions

NewFMConnector creates new FMConnector object.
NewFMQuery creates new FMQuery object.

# Constants

And operator.
Ascending -ascend.
BeginsWith -bw.
Contains -cn.
Custom -custom.
DateFormat is a format of date on a particular layout.
Delete -delete.
Descending -descend.
Duplicate -dup.
Edit -edit.
EndsWith -ew.
Equal -eq.
Find -findquery.
FindAll -findall.
FindAny findany.
FMDBNames adds –dbnames (Database names) query command.
GreaterThan -gt.
GreaterThanEqual -gte.
LessThan -lt.
LessThanEqual -lte.
New -new.
Not operator.
Or operator.
TimeFormat is a format of time on a particular layout.
TimestampFormat is a format of timestamp on a particular layout.
TypeContainer is a container type of the field.
TypeDate is a date type of the field.
TypeNumber is a number type of the field.
TypeText is a text type of the field.
TypeTime is a time type of the field.
TypeTimestamp is a timestamp type of the field.

# Variables

FileMakerErrorCodes are all error codes taken from FileMaker official documentation.

# Structs

DataSource store database name, layout name and time formats.
Field stands for field in a record.
FieldDefinition store information about a field in given layout.
FMConnector includes all the information about FM database to be able to connect to that.
FMError represents a FileMaker error.
FMQuery represent the query you are sending to the server.
FMQueryField is a field used in FMQuery.
FMQueryFieldGroup groups of fields used for the find request.
FMResultset is a collection of ResultSets.
FMSortField is a field that should be sorted during the query.
MetaData store fields' and related sets' meta information.
Record is FileMaker record.
RelatedSet is a set of records returned from FileMaker database.
RelatedSetDefinition is meta information of related set.
Resultset is a set of records with meta information.

# Type aliases

FieldsDefinitions is type of []FieldDefinition.
FieldType represents a type of the field.
FMAction is a type iof action can be done to the record.
FMFieldOp is type of operator for a FMField.
FMLogicalOp is a type for logical operators.
FMSortOrder is a type of order.