Skip to content

Commit

Permalink
Merge pull request #4 from Sybit-Education/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
stritti authored Mar 31, 2017
2 parents 7bb226a + 79ccd51 commit 85c1cc1
Show file tree
Hide file tree
Showing 15 changed files with 371 additions and 68 deletions.
38 changes: 26 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,18 @@ The API supports environment variable `http_proxy`. If the variable is set, it i

If `endpointUrl` contains `localhost` or `127.0.0.1` proxy settings are ignored automatically.

## Logging
### Logging

The Simple Logging Facade for Java [https://www.slf4j.org/](SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time.
The Simple Logging Facade for Java [https://www.slf4j.org/](SLF4J) serves as a simple facade or abstraction
for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired
logging framework at deployment time.

### Request Limits
The API of Airtable itself is limited to 5 requests per second. If you exceed this rate, you will receive a 429 status code and will
need to wait 30 seconds before subsequent requests will succeed.

## Access Base

## Access Table

## CRUD-Operations on table items
## CRUD-Operations on Table Records

## Select
Select List of items from table:
Expand Down Expand Up @@ -87,15 +89,29 @@ Table<Actor> actorTable = base.table("Actors", Actor.class);
Actor actor = actorTable.find("rec514228ed76ced1");
```

## Destroy
Use Destroy to delete a specific records of table:

+ `table(name).destroy(String id)`: delete record with `id` of table `name`

### Example
```Java
// detailed Example see TableDestroyTest.java
Base base = airtable.base(AIRTABLE_BASE);
Table<Actor> actorTable = base.table("Actors", Actor.class);
actorTable.destroy("recapJ3Js8AEwt0Bf");
```

## Annotations

Use the Gson Annotation @SerializedName to annotate Names which contain - or an emtpy Charakter.
Use the Gson Annotation `@SerializedName` to annotate Names which contain `-` or emtpy characters.

### Example
```Java

import com.google.gson.annotations.SerializedName;

//Column in Airtable is named "First- & Lastname", which is mapped to field "name".
@SerializedName("First- & Lastname")
private String name;
```
Expand All @@ -104,9 +120,9 @@ Use the Gson Annotation @SerializedName to annotate Names which contain - or an
+ [x] Airtable Configure
+ [x] configuration of `proxy`
+ [x] configuration of `AIRTABLE_API_KEY` & `AIRTABLE_BASE`
+ [ ] configuration of `requestTimeout`
+ [x] configuration of `requestTimeout`

+ [x] Select
+ [x] Select Records
+ [x] SelectAll
+ [x] Queries (`maxRecords`, `sort` & `view` )
+ [ ] Support of `filterByFormula`
Expand All @@ -116,7 +132,7 @@ Use the Gson Annotation @SerializedName to annotate Names which contain - or an

+ [ ] Create Record
+ [ ] Update Record
+ [ ] Delete Record
+ [x] Delete Record
+ [ ] Replace Record
+ General requirements
+ [ ] Automatic ObjectMapping
Expand Down Expand Up @@ -151,5 +167,3 @@ We use following libraries:
# License

MIT License, see [LICENSE](LICENSE)


43 changes: 28 additions & 15 deletions src/main/java/com/sybit/airtable/Airtable.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@


import com.mashape.unirest.http.Unirest;
import com.sybit.airtable.converter.ListConverter;
import com.sybit.airtable.converter.MapConverter;
import com.sybit.airtable.exception.AirtableException;
import com.sybit.airtable.vo.Attachment;
import com.sybit.airtable.vo.Thumbnail;
Expand Down Expand Up @@ -42,12 +44,11 @@
public class Airtable {

private static final Logger LOG = LoggerFactory.getLogger( Airtable.class );
private static final String ENDPOINT_URL = "https://api.airtable.com/v0";

private static final String AIRTABLE_API_KEY = "AIRTABLE_API_KEY";
private static final String AIRTABLE_BASE = "AIRTABLE_BASE";

private String endpointUrl;
private String apiKey;
private Configuration config;

/**
* Configure, <code>AIRTABLE_API_KEY</code> passed by Java property, enviroment variable
Expand Down Expand Up @@ -84,29 +85,32 @@ public Airtable configure() throws AirtableException {
*/
@SuppressWarnings("WeakerAccess")
public Airtable configure(String apiKey) throws AirtableException {
return configure(apiKey, ENDPOINT_URL);
return configure(new Configuration(apiKey, Configuration.ENDPOINT_URL));
}

/**
*
* @param apiKey
* @param endpointUrl
* @param config
* @return
* @throws com.sybit.airtable.exception.AirtableException Missing API-Key or Endpoint
*/
@SuppressWarnings("WeakerAccess")
public Airtable configure(String apiKey, String endpointUrl) throws AirtableException {
if(apiKey == null) {
public Airtable configure(Configuration config) throws AirtableException {
if(config.getApiKey() == null) {
throw new AirtableException("Missing Airtable API-Key");
}
if(endpointUrl == null) {
if(config.getEndpointUrl() == null) {
throw new AirtableException("Missing endpointUrl");
}

this.apiKey = apiKey;
this.endpointUrl = endpointUrl;
this.config = config;

setProxy(endpointUrl);
if(config.getTimeout() != null) {
LOG.info("Set connection timeout to: " + config.getTimeout() + "ms.");
Unirest.setTimeouts(config.getTimeout(), config.getTimeout());
}

setProxy(config.getEndpointUrl());

// Only one time
Unirest.setObjectMapper(new GsonObjectMapper());
Expand Down Expand Up @@ -188,20 +192,29 @@ public Base base(String base) throws AirtableException {
return b;
}

public Configuration getConfig() {
return config;
}

public void setConfig(Configuration config) {
this.config = config;
setProxy(config.getEndpointUrl());
}

/**
*
* @return
*/
public String endpointUrl() {
return endpointUrl;
return this.config.getEndpointUrl();
}

/**
*
* @return
*/
public String apiKey() {
return apiKey;
return this.config.getApiKey();
}

/**
Expand Down Expand Up @@ -233,7 +246,7 @@ private String getCredentialProperty(String key) {
}

public void setEndpointUrl(String endpointUrl) {
this.endpointUrl = endpointUrl;
this.config.setEndpointUrl(endpointUrl);
setProxy(endpointUrl);
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/sybit/airtable/Base.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public Base(String base, Airtable airtable) {
* Set Airtable object as parent.
* @param parent the base Airtable object.
*/
protected void setParent(Airtable parent) {
void setParent(Airtable parent) {
this.parent = parent;
}

Expand Down
72 changes: 72 additions & 0 deletions src/main/java/com/sybit/airtable/Configuration.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* The MIT License (MIT)
* Copyright (c) 2017 Sybit GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
*/
package com.sybit.airtable;

/**
* Configuration settings for Airtable.
* Used by class <code>Airtable</code> to configure basic settings.
*/
public class Configuration {

public static final String ENDPOINT_URL = "https://api.airtable.com/v0";

private String endpointUrl;
private String apiKey;
private Long timeout;

/**
* Configure API using given API Key and default endpoint.
*
* @param apiKey
*/
public Configuration(String apiKey) {
this(apiKey, ENDPOINT_URL);

}
/**
* Configure API using given API Key and default endpointURL.
*
* @param apiKey
* @param endpointUrl
*/
public Configuration(String apiKey, String endpointUrl) {
this.apiKey = apiKey;
this.endpointUrl = endpointUrl;
}

public String getEndpointUrl() {
return endpointUrl;
}

public void setEndpointUrl(String endpointUrl) {
this.endpointUrl = endpointUrl;
}

public String getApiKey() {
return apiKey;
}

public void setApiKey(String apiKey) {
this.apiKey = apiKey;
}

/**
* Get connection timeout.
* @return
*/
public Long getTimeout() {
return timeout;
}

/**
* Set connection timeout.
* @param timeout
*/
public void setTimeout(Long timeout) {
this.timeout = timeout;
}
}
5 changes: 3 additions & 2 deletions src/main/java/com/sybit/airtable/GsonObjectMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*
* @author fzr
*/
class GsonObjectMapper implements ObjectMapper{
class GsonObjectMapper implements ObjectMapper {
private static final Logger LOG = Logger.getLogger( GsonObjectMapper.class.getName() );
private final Gson gson;

Expand All @@ -25,11 +25,12 @@ public GsonObjectMapper() {
}

public <T> T readValue(String value, Class<T> valueType) {
LOG.log(Level.INFO, "readValue: \n" + value);
LOG.log(Level.FINE, "readValue: \n" + value);
return gson.fromJson(value, valueType);
}

public String writeValue(Object value) {
LOG.log(Level.FINE, "writeValue: \n" + value);
return gson.toJson(value);
}

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/com/sybit/airtable/Query.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ public interface Query {
List<Sort> getSort();

/**
* Define a filter formula.
*
* @return
* see https://support.airtable.com/hc/en-us/articles/203255215-Formula-Field-Reference
* @return get the filter formula.
*/
String filterByFormula();
}
39 changes: 34 additions & 5 deletions src/main/java/com/sybit/airtable/Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import com.mashape.unirest.request.GetRequest;
import com.sybit.airtable.exception.AirtableException;
import com.sybit.airtable.exception.HttpResponseExceptionHandler;
import com.sybit.airtable.vo.Delete;
import com.sybit.airtable.vo.RecordItem;
import com.sybit.airtable.vo.Records;
import org.apache.commons.beanutils.BeanUtils;
Expand Down Expand Up @@ -110,7 +111,7 @@ public String filterByFormula() {
* @throws HttpResponseException
*/
@SuppressWarnings("WeakerAccess")
public List<T> select(Query query) throws AirtableException, HttpResponseException {
public List<T> select(Query query) throws AirtableException {
HttpResponse<Records> response;
try {
GetRequest request = Unirest.get(getTableEndpointUrl())
Expand Down Expand Up @@ -272,7 +273,7 @@ private List<T> getList(HttpResponse<Records> response) {
* @return searched record.
* @throws AirtableException
*/
public T find(String id) throws AirtableException, HttpResponseException {
public T find(String id) throws AirtableException {

RecordItem body = null;

Expand Down Expand Up @@ -316,10 +317,38 @@ public T replace(T item) {

throw new UnsupportedOperationException("not yet implemented");
}

/**
* Delete Record by given id
*
* @param id
* @throws AirtableException
*/

public T destroy(T item) {
public void destroy(String id) throws AirtableException {

Delete body = null;

throw new UnsupportedOperationException("not yet implemented");
HttpResponse<Delete> response;
try {
response = Unirest.delete(getTableEndpointUrl() + "/" + id)
.header("accept", "application/json")
.header("Authorization", getBearerToken())
.asObject(Delete.class);
} catch (UnirestException e) {
throw new AirtableException(e);
}
int code = response.getStatus();

if(200 == code) {
body = response.getBody();
} else {
HttpResponseExceptionHandler.onResponse(response);
}

if(!body.isDeleted()){
throw new AirtableException("Record id: "+body.getId()+" could not be deleted.");
}
}

/**
Expand Down Expand Up @@ -423,7 +452,7 @@ private void setProperty(T retval, String key, Object value) throws IllegalAcces
private String key2property(String key) {

if(key.contains(" ") || key.contains("-") ) {
LOG.warn( "Annotate special characters using @SerializedName for property: [" + key + "]");
LOG.warn( "Annotate columns having special characters by using @SerializedName for property: [" + key + "]");
}
String property = key.trim();
property = property.substring(0,1).toLowerCase() + property.substring(1, property.length());
Expand Down
Loading

0 comments on commit 85c1cc1

Please sign in to comment.