How to use definitions stored in a DB to definitions in your source code? - database

I would like to get some ideas how to use definitions which are stored in a DB (which is used by your application) into the source code of the application.
Example:
Database
Cars
CarTypeDefinitions
A column of Cars links by a foreign key to a row in CarTypeDefinitions, therefore defines the type of the car which is contained in Cars.
Cars contains entries like 'Aston Martin DB8', 'Range Rover' and 'Mercedes Actros'.
CarTypeDefinitions contains entries like 'Sports car', 'SUV' and 'Truck'.
Source code
Now I would like to be able to use these definitions in my source code as well. So somehow we need to create some kind of mapping between a row in the CarTypeDefinitions table and a (preferably) type-safe implementation in the source code.
One possible implementation
The first thing which comes to my mind (and I am especially looking for other solutions or feedback on this one) would be to create an Enum ECarTypeDefinitions.
public enum ECarTypeDefinitions
{
SportsCar = 1,
SUV = 2,
Truck = 3
}
Now that we have a type-safe Enum we can use it e.g. like this:
public bool IsSportsCar(Car currentCar)
{
return (currentCar.CarType == ECarTypeDefinitions.SportsCar);
}
The contents of that enum would be auto-generated from the contents of the CarTypeDefinitions table (add two additional columns for name of the enum and its integer value).
This would also work the other way, e.g. generate the content of the CarTypeDefinitions DB table from the ECarTypeDefinitions Enum.
I'm keen to hear about other ways how to tackle this problem. How have you dealt with this?

I do it the way you have suggested. Some others prefer to combine all constants into a "Lookup" table. You can look at an example of some of the pros and cons here: http://weblogs.foxite.com/andykramek/archive/2009/05/10/8419.aspx
Edit: Here's a thought that may help spark further ideas from you.
Create a class for each Car Type:
public class SportsCarType
{
}
Now add an attribute to CarTypeDefinition:
public class CarTypeDefinition
{
...
public string typeName;
}
Populate the new attribute (for each type you have) using typeof:
...
carTypeDefinition.typeName = typeof(SportsCarType).Name;
...
Finally your new IsSportsCar method:
public bool IsSportsCar(Car currentCar)
{
return (currentCar.CarType.typeName == typeof(SportsCarType).Name);
}
I'm not familiar with Entity Framework so perhaps it has a way to allow this kind of thing to be more cleanly done. Also a little rusty on C#.

Related

How to build a list of dynamic strings in Flutter?

I'm coding an app/game where user inputs his own rules on textfields stored in a SQFLite database.
Rules are related to a friend, so it's in a class Friend, with an id, name, rule0, rule1, rule2...rule9. Which is REALLY annoying for a lot of reasons, but I think I need it to be in Friend class so it get stored with the right friend.id.
I got the obvious error 'only static members can be accessed on initializers' when i try
List<Strings> rules = [rule0, rule1];
or
List<dynamic> rules = [...];
Does anyone knows how I could fix this ?
Create a new class Rules and each rule has ID related to the right friend ?
Or if I can just create a dynamic list whithin Friend ?
Really lost on this. Any help is welcome.
class Friend {
int id;
String name;
String pic;
bool play;
String rule0;
String rule1;
String rule2;
String rule3;
String rule4;
String rule5;
String rule6;
String rule7;
String rule8;
String rule9;
Friend();
// i have then a fromMap() and a toMap() for the database
}
I'm not completely sure, but it seems like you're having trouble with both the SQL aspect as well as the class representation of your data.
If you know for sure there will only be a set number of rules, you could approach it in the way you currently have. The addition I'd do is to make a 'getter' function for the list of rules i.e.
List<String> get rules => [rule1, rule2, rule2, ...].where((item) => item != null).toList()
Note that if you were using a constructor, you could instead build the list in the constructor as follows:
class Friend {
int id;
String name;
String pic;
bool play;
String rule0;
String rule1;
String rule2;
String rule3;
String rule4;
String rule5;
String rule6;
String rule7;
String rule8;
String rule9;
List<String> rules;
Friend(
{this.id,
this.name,
this.pic,
this.play,
this.rule0,
this.rule1,
this.rule2,
this.rule3,
this.rule4,
this.rule5,
this.rule6,
this.rule7,
this.rule8,
this.rule9})
: rules = [
rule0,
rule1,
rule2,
rule3,
rule4,
rule5,
rule6,
rule7,
rule8,
rule9,
].where((item) => item != null).toList(growable: false);
}
I wouldn't recommend that though (or if you do, you should probably be making either rule* or rules private or maintaining state somehow). The list of strings doesn't store references to the rule0, rule1, ... strings but rather stores the strings themselves. You could get around this by making a Rule class and making rule0-9 final, but that's getting a bit complicated.
It most likely makes more sense for this to be a dynamic list of items. SQL doesn't handle that, so you're going to have to make a separate table for rules.
You'll have two tables something like this, where id are both PRIMARY KEYs and friendId is a FOREIGN KEY:
Friend(id, name, pic, play) and Rule(id, friendId, text)
Saving and updating will become more complicated now. You'll have to be more careful about maintaining the list of rules in the database, but it isn't all that difficult. If you know that you'll only be writing to the list from one location (i.e. one class), you could keep the difference between what the class's current state and the initial state were, but realistically unless you're dealing with 10's of thousands of rules, it probably won't matter appreciably.

Design pattern to process different file types in OOP

I need to process a big set of files that at the moment are all loaded into memory on a List.
i.e:
List(FileClass) Files;
Use:
Reader.Files; //List of files of the type
File Class has one attribute to match each FileInfo object property i.e: Name,CreateDate,etc.
Also has a List of Lines of the type (LineNumber, Data).
Now I need to create an logic to interpret these files. They all have different logic interpreteations and they will be loaded on to their correspondent Business Object.
i.e:
Model model = new Model()
.emp => Process => Employee Class
.ord => Process => Order Class
model.AddObject(emp);
model.AddObject(ord);
My question what is the best design pattern for a problem of this sort.
All I can think of is... something like this:
public ProcessFiles(List<Files> Files)
{
Model model = new Model()
var obj;
foreach(file in Files)
{
switch (File.GetExtension(file))
{
case "emp":
obj = BuildEmployee(file) //returns Employee class type
break;
case "ord":
obj = BuildOrder(file) //returns Order class type
break;
}
model.AddObject(obj);
}
}
Is there a better way to approach this?
This solution looks procedural to me, is there a better Object Oriented Approach to it?
Cheers
UPDATE:
I've come across a few options to solve this:
1)- Use of Partial classes for separation of concerns.
I have a data model that I don't want to mix File processing, Database use, etc (Single Responsibility)
DATA MODEL:
public partial class Employee
{
public int EmployeeID;
public string FirstName;
public string LastName;
public decimal Salary;
}
INTERPRETER/FILE PARSER:
This partial class defines the logic to parse .emp files.
// This portion of the partial class to separate Data Model
from File processing
public partial class Employee
{
public void ProcessFile(string FileName)
{
//Do processing
}
...
}
Intepreter Object
public class Interpreter : IInterpreter
{
foreach(file in Files)
{
switch (fileExtension)
{
case .emp
Employee obj= new Employee();
case .ord
Order obj = new Order(file);
}
obj.ProcessFile(File)
Model.AddObject(emp)
}
}
2)- Perhaps using some sort of Factory Pattern...
The input is the file with an extension type.
This drives the type of object to be created (i.e: Employee, Order, anything) and also the logic to parse this file. Any ideas?
Well, it seems that you want to vary the processing behaviour based on the file type. Behaviour and Type being keywords. Does any behavioural pattern suit your requirement?
Or is it that the object creation is driven by the input file type? Then creation and type become important keywords.
You might want to take a look at strategy and factory method patterns.
Here is something from the book Refactoring to Patterns:
The overuse of patterns tends to result from being patterns happy. We
are patterns happy when we become so enamored of patterns that we
simply must use them in our code. A patterns-happy programmer may work
hard to use patterns on a system just to get the experience of
implementing them or maybe to gain a reputation for writing really
good, complex code.
A programmer named Jason Tiscione, writing on SlashDot (see
http://developers.slashdot.org/comments.pl?sid=33602&cid=3636102),
perfectly caricatured patterns-happy code with the following version
of Hello World. ..... It is perhaps impossible to avoid being patterns
happy on the road to learning patterns. In fact, most of us learn by
making mistakes. I've been patterns happy on more than one occasion.
The true joy of patterns comes from using them wisely.

JPA map entity with array datatype

I have a table which contains a column of type: integer[]
I'm trying to map my entity to this table and I've tried the following suggestion of:
#ElementCollection
private ArrayList<Integer> col;
public MyEntity() {
col = new ArrayList<>();
}
However I get the following error: Illegal attempt to map a non collection as a #OneToMany, #ManyToMany or #CollectionOfElements
Not sure how to get around this. I'm open to changing the entity's datatype, but I would prefer not to move this property into its own table/entity. Is there another solution? Thanks.
The field must be of type List<Integer>, not ArrayList<Integer>.
The JPA engine must be able to use its own List implementation, used for lazy-loading, dirty checking, etc.
It's a good idea in general to program on interfaces rather than implementations, and it's a requirement to do it in JPA entities.

Displaying Mutable PostgreSQL Arrays in the NetBeans Master/Detail Sample Form using JPA 1.0

Some Background
I have a game database with a table called Games that has multiple attributes and one called Genres. The Genres attribute is defined as an integer[] in PostgreSQL. For the sake of simplicity, I'm not using any foreign key constraints, but essentially each integer in this array is a foreign key constraint on the id attribute in the Genres table. First time working with the NetBeans Master/Detail Sample Form and Java persistence and it's been working great so far except for 1 thing. I get this error when the program tries to display a column that has a 1-dimensional integer array. In this example, the value is {1, 11}.
Exception Description: The object [{1,11}], of class [class org.postgresql.jdbc3.Jdbc3Array], from mapping [oracle.toplink.essentials.mappings.DirectToFieldMapping[genres-->final.public.games.genres]] with descriptor [RelationalDescriptor(finalproject.Games --> [DatabaseTable(final.public.games)])], could not be converted to [class [B].
Exception [TOPLINK-3002] (Oracle TopLink Essentials - 2.0.1 (Build b09d-fcs (12/06/2007))): oracle.toplink.essentials.exceptions.ConversionException
My Research
From what I've been able to read, it looks like PostgreSQL arrays need something special done to them before you can display and edit them in this template. By default, the sample form uses TopLink Essentials (JPA 1.0) as its persistence library, but I can also use Hibernate (JPA 1.0).
Here is the code that needs to be changed in some way. From the Games.java file:
#Entity
#Table(name = "games", catalog = "final", schema = "public")
#NamedQueries({
// omitting named queries
#NamedQuery(name = "Games.findByGenres", query = "SELECT g FROM Games g WHERE g.genres = :genres")
})
public class Games implements Serializable {
#Transient
private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
private static final long serialVersionUID = 1L;
// omitting other attributes
#Column(name = "genres")
private Serializable genres;
// omitting constructors and other getters/setters
public Serializable getGenres() {
return genres;
}
public void setGenres(Serializable genres) {
Serializable oldGenres = this.genres;
this.genres = genres;
changeSupport.firePropertyChange("genres", oldGenres, genres);
}
} // end class Games
Here are also some of the sites that might have the solution that I'm just not understanding:
https://forum.hibernate.org/viewtopic.php?t=946973
http://blog.xebia.com/2009/11/09/understanding-and-writing-hibernate-user-types/
// omitted hyperlink due to user restriction
Attempted Solutions
I'm able to get the data to display if I change the type of genres to String, but it is immutable and I cannot edit it. This is what I changed to do this:
#Column(name = "genres")
private String genres;
public String getGenres() {
return genres;
}
public void setGenres(String genres) {
String oldGenres = this.genres;
this.genres = genres;
changeSupport.firePropertyChange("genres", oldGenres, genres);
}
I also attempted to create a UserType file for use with Hibernate (JPA 1.0), but had no idea what was going wrong there.
I also attempted to use the #OneToMany and other tags, but these aren't working probably because I'm not using them properly.
What I'm Looking For
There has to be a simple way to get this data to display and make it editable, but since I'm completely new to persistence, I have no idea what to do.
The effort put into your question shows. Unfortunately JPA does not currently support PostgreSQL arrays. The fundamental problem is that arrays are not frequently used in many other databases frequently and so heavy reliance on them is somewhat PostgreSQL specific. Thus you can expect that general cross-db persistence API's are not generally going to support them well if at all. JPA is no exception, having currently no support for PostgreSQL arrays.
I have been looking at writing my own persistence API in Java that would support arrays, but it hasn't happened yet, would be PostgreSQL-only when written, and would be based on a very different principle than JPA and friends.

How to adjust constraints / DB mapping for Map within grails domain class

Following grails domain class:
class MyClass {
Map myMap
}
Now for myMap, grails automatically creates a new table for the elements in the map. However if I add elements which are too long (e.g. 1024 characters), I get a DB error.
Can I somehow tell grails to make the respective column in myMap's table big enough to allow for larger Strings, or do I have to do this manually in the DB?
I already tried
static constraints = {
myMap(maxSize:1024)
}
which doesn't work (as expected because maxSize should refer to the Map's values and not to the Map itself).
If not via constraints, maybe there's a way to do it via
static mapping { ... }
?
An alternative approach I used successfully was to push the map out into a collection of a collaborator domain class.
class DynaProperty {
String name
String value
static belongsTo = MyClass
static constraints = {
value(maxSize:4000) //Or whatever number is appropriate
}
}
And then in MyClass:
class MyClass {
static hasMany = [dynaProperties:DynaProperty]
}
This is almost a map, and it gives you the ability to use dynamic finders to pull up an individual entry.
what are you trying to accomplish? Is there always the same number of things in the map? If there is you should define those properties on your class.
You can see the problem with your current approach -- there is no way to figure out what might be in the map until runtime, so how can grails possibly create a columns for it? Im surprised it even worked to begin with...

Resources