AmpersandTarski / Ampersand

Build database applications faster than anyone else, and keep your data pollution free as a bonus.
http://ampersandtarski.github.io/
GNU General Public License v3.0
40 stars 8 forks source link

Make Generics(.php) platform independent #197

Closed Michiel-s closed 8 years ago

Michiel-s commented 9 years ago

This issue describes a proposal to change the way by which the generated info from ampersand is provided to the backend framework. Currently all information is generated to Generics.php, a php file containing several php arrays. I propose to change this to multiple JSON files. JSON because it makes the generated information platform independent. Multiple files because that is more convenient to manually browse through, to e.g. bug fix.

The files are:

Implement in backend (Michiel):

All files should satisfy the JSON specification (see http://www.json.org for an introduction) php arrays can be easily converted into json arrays and objects.

mysql-installer.json

{ "allDBstructQueries" : 
  [ "<query1>"
  , "<query2>"
  , "<etc>"
  ]
, "allDefPopQueries" :
  [ "<query1>"
  , "<query2>"
  , "<etc>
  ]
}

concepts.json

[ { name : "ConceptA"
  , type : "OBJECT"
  , generalizations : [ "ConceptX", ConceptY, "etc" ]
  , specializations : [ "ConceptB", ConceptC, "etc" ]
  , affectedConjuncts : [ "conj1", "conj2", "etc" ]
  , interfaces : [ "ifcA", "ifcB", "etc" ]
  , defaultViewId : "<name of default view>"
  , conceptTable : { name : "<table name>"
                            , cols : [ "<col1>", "<col2>", etc ]
                            }
}
, { another concept }
]

relations.json tableOf specifies if relation is administrated in table of srcConcept, tgtConcept or its own (n-n table)

[ { name : "rel"
  , signature : "rel[SrcConcept*TgtConcept]"
  , srcConcept : "SrcConcept"
  , tgtConcept : "TgtConcept"
  , uni : true|false
  , tot: true|false
  , inj : true|false
  , sur : true|false
  , affectedConjuncts : ["conj1", "conj2", "etc"]
  , mysqlTable : { name : "<table name>"
                         , tableOf : "src"|"tgt"|null
                         , srcCol : {name : "<col name>", null : true|false, unique : true|false}
                         , tgtCol : {name : "<col name>", null : true|false, unique : true|false}
                         }
  }
, { second relation }
, { etc }
]

roles.json maintains = rule names/ids of rules that are maintained by this role interfaces = interface ids of interfaces that are available to this role (including the interfaces for every role)

[ { id : <increasing nr>
  , name : "<role name>"
  , maintains : ["<rule1>", "<rule2>", "<etc>"]
  , interfaces : ["<interface1>", "<interface2>", "<etc>"]
  }
, { second role }
, { etc }
]

rules.json

interfaces.json

settings.json generateConstants from Generate.hs (isDev and autoRefreshInterval are obsolete) mysql settings from ObjBinGen.hs

{ "versionInfo" : "<versionInfo>"
, "contextName" : "<contextName>"
, "mysql-settings" : 
  { "dbHost" : "<dbHost>"
  , "dbName" : "<dbName>"
  , "dbUser" : "<dbUser>"
  , "dbPass" : "<dbPass>"
  , "signalTableName" : "<signalTableName>"
  }
}
hanjoosten commented 9 years ago

I think this is a good idea. The way to go would be to create these files beside the current .php files. Only when we all are happy with the contents in the .json files, and the frontend fully uses the .json files, the .php files will become obsolete.

hanjoosten commented 9 years ago

The approach to this (from a Haskell pov, would be to create a haskell data structure for each of these files, populate them using fspec. Then, by using the Aeson package to convert each of them to a json file. This should be pretty straitforward.

hanjoosten commented 9 years ago

Hi Michiel, I have built relations.json in a slightly different way. I have put all conjuncts of that relation in one array. That is closer to the Ampersand structure. A conjunct itself isn't signal or invariant. However, the rule where the conjunct is from has that property. It is possible to denormalize the property of the rule to a property of a conjunct, but that might have nasty consequences later on. I think that in the end you'd have nicer code when we keep it this way.

However, if you have a good reason to split at this level, then it can be done.

hanjoosten commented 9 years ago

I also added prettyprinting of the .json files

hanjoosten commented 9 years ago

Without any specification of Michiel, I made a rules.json. @Michiel-s , Let me know what you think about this!

Michiel-s commented 9 years ago

@hanjoosten

Take a look at the output of mysql-installer.json:

{
    "allDBstructQueries": [
        "$allDBstructQueries =",
        "  array ( 'CREATE TABLE \"__SessionTimeout__\"",
        "            ( \"SESSION\" VARCHAR(255) UNIQUE NOT NULL",
        "            , \"lastAccess\" BIGINT NOT NULL",
        "            ) ENGINE=InnoDB DEFAULT CHARACTER SET UTF8 COLLATE UTF8_BIN'",
        "        , 'CREATE TABLE \"__History__\"",
...

A couple of things need fixing:

Michiel-s commented 9 years ago

@hanjoosten

The rules.json looks good, except for the 'expSQL' field of a pairView item. It contains '\n' and space characters. These should be removed.

Furthermore, I saw that you've added a 'segmentNr'. Can you guarantee that these are put in the right order in the pairView array?

Michiel-s commented 9 years ago

@hanjoosten

The relations.json is ok, except for the 'signature' field of a relations. It now contains [Src*Tgt]. However, the full signature should also contain the relation name: rel[Src*Tgt]

Could you also add the multiplicities. UNI, TOT, INJ, SUR:

[ { name : "rel"
  , signature : "rel[SrcConcept*TgtConcept]"
  , srcConcept : "SrcConcept"
  , tgtConcept : "TgtConcept"
  , srcMin : 0 or 1
  , srcMax : 1 or null
  , tgtMin : 0 or 1
  , tgtMax : 1 or null
  , affectedConjuncts : ["conj1", "conj2", "etc"]
  }
, { second relation }
, { etc }
]
Michiel-s commented 9 years ago

I've updated the initial post and added specification for concepts.json

hanjoosten commented 9 years ago

On your comments about mysql-installer.json: Hmm. You are right. I went too fast. I could have noticed most of your issues myself. Sorry. About order in Json: There isn't any! So I added a seqNr to the queries. It looks however that the array is kept in order anyway. Not sure if that is by accident or if you may trust that ordering.

hanjoosten commented 9 years ago

Also fixed the other issues unto this comment.

hanjoosten commented 9 years ago

Michiel, I am not sure the segments of the viewdefinitions in concepts.json are generated correctly. Do you have a nice test-model somewhere?

hanjoosten commented 8 years ago

@Michiel-s more wishes for the .json files? let me know!

Michiel-s commented 8 years ago

@hanjoosten

For some reason I don't see roles.json yet. Could you:

roles.json maintains = rule names/ids of rules that are maintained by this role interfaces = interface ids of interfaces that are available to this role (including the interfaces for every role)

[ { id : <increasing nr>
  , name : "<role name>"
  , maintains : ["<rule1>", "<rule2>", "<etc>"]
  , interfaces : ["<interface1>", "<interface2>", "<etc>"]
  }
, { second role }
, { etc }
]
Michiel-s commented 8 years ago

Implemented views.json in 0c4fad46353a4732753c0dacb66f37c534c49cd1

Michiel-s commented 8 years ago

@hanjoosten

I've updated the specs for the relations.json. Could you:

relations.json tableOf specifies if relation is administrated in table of srcConcept (i.e. "src"), tgtConcept (i.e. "tgt") or its own n-n table (i.e. null).

[ { name : "rel"
  , signature : "rel[SrcConcept*TgtConcept]"
  , srcConcept : "SrcConcept"
  , tgtConcept : "TgtConcept"
  , uni : true|false
  , tot: true|false
  , inj : true|false
  , sur : true|false
  , affectedConjuncts : ["conj1", "conj2", "etc"]
  , mysqlTable : { name : "<table name>"
                         , tableOf : "src"|"tgt"|null
                         , srcCol : {name : "<col name>", null : true|false, unique : true|false}
                         , tgtCol : {name : "<col name>", null : true|false, unique : true|false}
                         }
  }
, { second relation }
, { etc }
]
Michiel-s commented 8 years ago

Hi @hanjoosten

I've updated the concept.json specs. Please:

concepts.json

[ { name : "ConceptA"
  , type : "OBJECT"
  , generalizations : [ "ConceptX", ConceptY, "etc" ]
  , specializations : [ "ConceptB", ConceptC, "etc" ]
  , affectedConjuncts : [ "conj1", "conj2", "etc" ]
  , interfaces : [ "ifcA", "ifcB", "etc" ]
  , defaultViewId : "<name of default view>"
  , conceptTable : { name : "<table name>"
                            , cols : [ "<col1>", "<col2>", etc ]
                            }
}
, { another concept }
]
Michiel-s commented 8 years ago

Implemented roles.json in 72458e7b5634446c3cac15c2374e25a20a8c296b

Michiel-s commented 8 years ago

All json files are implemented in the backend.

hanjoosten commented 8 years ago

I cleaned up conform issue #198. I also modified the Cruds a little in the interface.json file, as we have spoken of before. The cruds are now in one object together, at all places. It might be that some of the connections with the backend is broken by that action. @Michiel-s, please check this, then you can close this issue again.

Michiel-s commented 8 years ago

All ok.